@cloud-ru/ds-uikit-product-header 2.0.3 → 2.0.4
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 +6 -0
- package/dist/cjs/components/HeaderLayout/HeaderLayout.js +1 -1
- package/dist/cjs/components/HeaderLayout/styles.module.css +2 -6
- package/dist/cjs/components/MainMenu/helperComponents/MenuBottom/MenuBottom.js +1 -1
- package/dist/cjs/components/MainMenu/helperComponents/MenuMobile/MenuMobile.js +2 -1
- package/dist/cjs/components/MainMenu/helperComponents/ScrollWithAnimatedStickyPanel/ScrollWithAnimatedStickyPanel.js +18 -6
- package/dist/cjs/components/UserMenu/UserMenu.js +5 -4
- package/dist/cjs/components/UserMenu/hooks/useLogoutItem.d.ts +2 -2
- package/dist/cjs/components/UserMenu/hooks/useLogoutItem.js +12 -9
- package/dist/cjs/components/UserMenu/hooks/useUserMenuItems.js +3 -3
- package/dist/cjs/components/UserMenu/styles.module.css +10 -1
- package/dist/cjs/constants.d.ts +0 -1
- package/dist/cjs/constants.js +1 -3
- package/dist/cjs/style.css +12 -7
- package/dist/esm/components/HeaderLayout/HeaderLayout.js +1 -1
- package/dist/esm/components/HeaderLayout/styles.module.css +2 -6
- package/dist/esm/components/MainMenu/helperComponents/MenuBottom/MenuBottom.js +2 -2
- package/dist/esm/components/MainMenu/helperComponents/MenuMobile/MenuMobile.js +3 -2
- package/dist/esm/components/MainMenu/helperComponents/ScrollWithAnimatedStickyPanel/ScrollWithAnimatedStickyPanel.js +18 -6
- package/dist/esm/components/UserMenu/UserMenu.js +8 -7
- package/dist/esm/components/UserMenu/hooks/useLogoutItem.d.ts +2 -2
- package/dist/esm/components/UserMenu/hooks/useLogoutItem.js +9 -9
- package/dist/esm/components/UserMenu/hooks/useUserMenuItems.js +3 -3
- package/dist/esm/components/UserMenu/styles.module.css +10 -1
- package/dist/esm/constants.d.ts +0 -1
- package/dist/esm/constants.js +0 -2
- package/dist/esm/style.css +12 -7
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +12 -12
- package/src/components/HeaderLayout/HeaderLayout.tsx +3 -3
- package/src/components/HeaderLayout/styles.module.scss +2 -7
- package/src/components/MainMenu/helperComponents/MenuBottom/MenuBottom.tsx +2 -2
- package/src/components/MainMenu/helperComponents/MenuMobile/MenuMobile.tsx +3 -2
- package/src/components/MainMenu/helperComponents/ScrollWithAnimatedStickyPanel/ScrollWithAnimatedStickyPanel.tsx +21 -10
- package/src/components/UserMenu/UserMenu.tsx +11 -7
- package/src/components/UserMenu/hooks/useLogoutItem.tsx +12 -12
- package/src/components/UserMenu/hooks/useUserMenuItems.ts +4 -4
- package/src/components/UserMenu/styles.module.scss +12 -1
- package/src/constants.ts +0 -3
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.0.4 (2026-10-01)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **FF-9223:** paint in red logout button and pin to bottom on mobile, correct hiding for mobile header, remove tooltip on mobile ([20f5b0c](https://github.com/cloud-ru-tech/snack-v2/commit/20f5b0c8e3a13216057169657c9d2b6283a17275))
|
|
11
|
+
|
|
6
12
|
## 2.0.3 (2026-09-30)
|
|
7
13
|
|
|
8
14
|
**Note:** Version bump only for package @ds/uikit-product-header
|
|
@@ -13,5 +13,5 @@ const useMobileLayout_1 = require("../../hooks/useMobileLayout");
|
|
|
13
13
|
const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
|
|
14
14
|
function HeaderLayout({ menu, logo, select, breadcrumbs, toolbar, className, ...rest }) {
|
|
15
15
|
const isMobile = (0, useMobileLayout_1.useMobileLayout)();
|
|
16
|
-
return ((0, jsx_runtime_1.jsxs)("header", { className: (0, classnames_1.default)(styles_module_scss_1.default.header, className), "data-mobile": isMobile || undefined, ...(0, utils_1.extractSupportProps)({ 'data-test-id': constants_1.TEST_IDS.headerLayout.root, ...rest }), children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.top, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.left, children: [logo && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: logo }), menu && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'vertical' }), menu, isMobile && (0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'vertical' })] })), !isMobile && select && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'vertical' }), select] })), !isMobile && breadcrumbs && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'vertical' }), breadcrumbs] }))] }), (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.right, children: toolbar })] }), (0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'horizontal' }), isMobile &&
|
|
16
|
+
return ((0, jsx_runtime_1.jsxs)("header", { className: (0, classnames_1.default)(styles_module_scss_1.default.header, className), "data-mobile": isMobile || undefined, ...(0, utils_1.extractSupportProps)({ 'data-test-id': constants_1.TEST_IDS.headerLayout.root, ...rest }), children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.top, children: [(0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.left, children: [logo && (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: logo }), menu && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'vertical' }), menu, isMobile && (0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'vertical' })] })), !isMobile && select && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'vertical' }), select] })), !isMobile && breadcrumbs && ((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)("div", { className: styles_module_scss_1.default.breadcrums, children: breadcrumbs })] }))] }), (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.right, children: toolbar })] }), (0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'horizontal' }), isMobile && breadcrumbs && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.breadcrums, children: breadcrumbs }), (0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'horizontal' })] }))] }));
|
|
17
17
|
}
|
|
@@ -7,12 +7,8 @@
|
|
|
7
7
|
padding:0 var(--sn-primitive-dimension-4, 4px);
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
.
|
|
11
|
-
|
|
12
|
-
display:flex;
|
|
13
|
-
align-items:center;
|
|
14
|
-
box-sizing:border-box;
|
|
15
|
-
height:var(--sn-primitive-dimension-24, 24px);
|
|
10
|
+
.breadcrums{
|
|
11
|
+
padding:0 var(--sn-primitive-dimension-8, 8px);
|
|
16
12
|
}
|
|
17
13
|
|
|
18
14
|
.left{
|
|
@@ -12,5 +12,5 @@ const constants_1 = require("../../../../constants");
|
|
|
12
12
|
const utils_1 = require("../../utils");
|
|
13
13
|
const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
|
|
14
14
|
function MenuBottom({ settingItems, leftBottom }) {
|
|
15
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.bottom, "data-test-id": constants_1.TEST_IDS.mainMenu.leftBottom, children: [Boolean(settingItems?.length) && ((0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.bottomItems, "data-test-id": constants_1.TEST_IDS.mainMenu.leftBottomItems, children: settingItems?.map(item => ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [item.divider === 'before' && (0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'horizontal', className: styles_module_scss_1.default.bottomDivider }), (0, jsx_runtime_1.jsx)(uikit_product_card_predefined_1.
|
|
15
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.bottom, "data-test-id": constants_1.TEST_IDS.mainMenu.leftBottom, children: [Boolean(settingItems?.length) && ((0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.bottomItems, "data-test-id": constants_1.TEST_IDS.mainMenu.leftBottomItems, children: settingItems?.map(item => ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [item.divider === 'before' && (0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'horizontal', className: styles_module_scss_1.default.bottomDivider }), (0, jsx_runtime_1.jsx)(uikit_product_card_predefined_1.CardNavigation, { ...(item.href ? { href: item.href, as: 'a' } : { as: 'button', type: 'button' }), title: item.label, icon: (0, utils_1.getLinkEmblem)(item), onClick: item.onClick, "data-test-id": `header__drawer-menu__setting-${item.id}` }), item.divider === 'after' && (0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'horizontal', className: styles_module_scss_1.default.bottomDivider })] }, item.id))) })), leftBottom] }));
|
|
16
16
|
}
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.MenuMobile = MenuMobile;
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
8
|
const divider_1 = require("@cloud-ru/ds-divider");
|
|
9
|
+
const list_1 = require("@cloud-ru/ds-list");
|
|
9
10
|
const react_1 = require("react");
|
|
10
11
|
const constants_1 = require("../../../../constants");
|
|
11
12
|
const mobileOverlays_1 = require("../../../../mobileOverlays");
|
|
@@ -38,5 +39,5 @@ function MenuMobile({ open = false, setOpen, settingItems, platformGroups, segme
|
|
|
38
39
|
const handleClose = (0, react_1.useCallback)(() => {
|
|
39
40
|
setOpen?.(false);
|
|
40
41
|
}, [setOpen]);
|
|
41
|
-
return ((0, jsx_runtime_1.jsx)(mobileOverlays_1.MobileDrawerCustom, { open: open, onClose: handleClose, position: 'bottom', className: styles_module_scss_1.default.drawerMobile, swipeEnabled: false, "data-test-id": constants_1.TEST_IDS.mainMenu.drawerMobile, closeOnPopstate: true, snapPoints:
|
|
42
|
+
return ((0, jsx_runtime_1.jsx)(mobileOverlays_1.MobileDrawerCustom, { open: open, onClose: handleClose, position: 'bottom', className: styles_module_scss_1.default.drawerMobile, swipeEnabled: false, "data-test-id": constants_1.TEST_IDS.mainMenu.drawerMobile, closeOnPopstate: true, snapPoints: list_1.SNAP_POINTS_PRESET.full, disableMotions: true, children: (0, jsx_runtime_1.jsx)(ScrollWithAnimatedStickyPanel_1.ScrollWithAnimatedStickyPanel, { panel: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(MenuHeaderBrand_1.MenuHeaderBrand, { logo: logo, onClose: handleClose, className: styles_module_scss_1.default.menuHeader, isMobile: true }), (0, jsx_runtime_1.jsx)(divider_1.Divider, { orientation: 'horizontal' })] }), children: (0, jsx_runtime_1.jsxs)(MountAnimation_1.MountAnimation, { className: styles_module_scss_1.default.scrollMobile, type: 'fade-slide-up', children: [leftTop, search && (0, jsx_runtime_1.jsx)(Search_1.Search, { ...search, ref: searchRef, isMobile: true }), !isSearching && favorite && (0, jsx_runtime_1.jsx)(Favorites_1.Favorites, { favorite: favorite, servicesById: servicesById, isMobile: true }), hasSegments && ((0, jsx_runtime_1.jsx)(useMainMenuDnd_1.MainMenuDndContext, { children: (0, jsx_runtime_1.jsx)(Content_1.Content, { isMobile: true, searchValue: search && search.value, rightTop: rightTop, favorite: favorite, segments: segments, searchGroups: resultItems, segmentPrefs: segmentPrefs, activeSegmentId: activeSegmentId, onActiveSegmentChange: onActiveSegmentChange, onSegmentOrderChange: onSegmentOrderChange, onSegmentExpandedChange: onSegmentExpandedChange, onSegmentServiceClick: onSegmentServiceClick, loading: loading }) })), !isSearching && hasBottomItems && (0, jsx_runtime_1.jsx)(MenuBottom_1.MenuBottom, { settingItems: settingItems, leftBottom: leftBottom })] }) }) }));
|
|
42
43
|
}
|
|
@@ -8,6 +8,10 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
8
8
|
const scroll_1 = require("@cloud-ru/ds-scroll");
|
|
9
9
|
const react_1 = require("react");
|
|
10
10
|
const styles_module_scss_1 = __importDefault(require('./styles.module.css'));
|
|
11
|
+
// Упругая прокрутка у верхней границы (touch-скролл на мобильных не "упирается" жёстко в 0 —
|
|
12
|
+
// контент можно немного "оттянуть" дальше) даёт scrollTop, не совпадающий с реальным положением
|
|
13
|
+
// контента в этот момент. Диапазон запаса — единицы пикселей; двух хватает с большим запасом.
|
|
14
|
+
const TOP_OVERSCROLL_EPSILON_PX = 2;
|
|
11
15
|
function ScrollWithAnimatedStickyPanel({ panel, children }) {
|
|
12
16
|
const [positions, setPositions] = (0, react_1.useState)({ panelTopShift: 0, containerScroll: 0 });
|
|
13
17
|
const [panelHeight, setPanelHeight] = (0, react_1.useState)(0);
|
|
@@ -20,6 +24,13 @@ function ScrollWithAnimatedStickyPanel({ panel, children }) {
|
|
|
20
24
|
return;
|
|
21
25
|
const panelHeight = panelRef.current.offsetHeight;
|
|
22
26
|
setPanelHeight(panelHeight);
|
|
27
|
+
// У верхней границы панель всегда полностью видна — не доверяем накопленному diff. Иначе
|
|
28
|
+
// "лишний" ход упругой прокрутки у самого верха читается как скролл вниз и на возврате к
|
|
29
|
+
// началу списка панель может остаться скрытой, хотя пользователь как раз скроллит наверх.
|
|
30
|
+
if (target.scrollTop <= TOP_OVERSCROLL_EPSILON_PX) {
|
|
31
|
+
setPositions({ panelTopShift: 0, containerScroll: target.scrollTop });
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
23
34
|
setPositions(prev => {
|
|
24
35
|
const diff = prev.containerScroll - target.scrollTop;
|
|
25
36
|
return {
|
|
@@ -28,10 +39,11 @@ function ScrollWithAnimatedStickyPanel({ panel, children }) {
|
|
|
28
39
|
};
|
|
29
40
|
});
|
|
30
41
|
}, []);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
const setPanelRef = (0, react_1.useCallback)((element) => {
|
|
43
|
+
if (element) {
|
|
44
|
+
setPanelHeight(element.offsetHeight);
|
|
45
|
+
panelRef.current = element;
|
|
46
|
+
}
|
|
47
|
+
}, []);
|
|
48
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.container, style: { '--snack-autohide-panel-height': `${panelHeight}px` }, children: [(0, jsx_runtime_1.jsx)(scroll_1.Scroll, { barHideStrategy: 'never', overflow: { x: 'hidden' }, onScroll: handleScroll, children: children }), (0, jsx_runtime_1.jsx)("div", { className: styles_module_scss_1.default.panel, ref: setPanelRef, style: { top: positions.panelTopShift }, children: panel })] }));
|
|
37
49
|
}
|
|
@@ -28,6 +28,9 @@ function UserMenu({ profile = {}, open: openProp, setOpen: setOpenProp, onLogout
|
|
|
28
28
|
const comfortClassName = (0, useDesktopComfortClassName_1.useDesktopComfortClassName)();
|
|
29
29
|
const [open = false, setOpen] = (0, utils_1.useValueControl)({ value: openProp, onChange: setOpenProp });
|
|
30
30
|
const { fullName = '', inviteCount } = profile;
|
|
31
|
+
const handleClose = (0, react_1.useCallback)(() => {
|
|
32
|
+
setOpen(false);
|
|
33
|
+
}, [setOpen]);
|
|
31
34
|
const { pinTop, items: menuItems, pinBottom, } = (0, useUserMenuItems_1.useUserMenuItems)({
|
|
32
35
|
isMobile,
|
|
33
36
|
profile,
|
|
@@ -36,9 +39,7 @@ function UserMenu({ profile = {}, open: openProp, setOpen: setOpenProp, onLogout
|
|
|
36
39
|
organizationItems,
|
|
37
40
|
bottomItems,
|
|
38
41
|
settingItems,
|
|
39
|
-
onClose:
|
|
40
|
-
setOpen(false);
|
|
41
|
-
},
|
|
42
|
+
onClose: handleClose,
|
|
42
43
|
onLogout,
|
|
43
44
|
});
|
|
44
45
|
const trigger = (0, react_1.useMemo)(() => ((0, jsx_runtime_1.jsx)(HeaderButton_1.HeaderButton, { tooltip: { tip: triggerTooltip }, isMobile: isMobile, onClick: () => {
|
|
@@ -50,5 +51,5 @@ function UserMenu({ profile = {}, open: openProp, setOpen: setOpenProp, onLogout
|
|
|
50
51
|
appearance: 'primary',
|
|
51
52
|
}
|
|
52
53
|
: undefined, "data-test-id": constants_1.TEST_IDS.userMenu.button, icon: (0, jsx_runtime_1.jsx)(avatar_1.Avatar, { appearance: 'red', size: 's', name: fullName, showTwoSymbols: true }), "data-pressed": open })), [fullName, inviteCount, onClick, open, setOpen, isMobile, triggerTooltip]);
|
|
53
|
-
return ((0, jsx_runtime_1.jsx)(list_1.Droplist, { open: open, onOpenChange: setOpen, size: 'm', selection: SELECTION_STUB, pinTop: pinTop, items: menuItems, pinBottom: pinBottom, scroll: !isMobile, trigger: 'click', placement: 'bottom-end', className: (0, classnames_1.default)(styles_module_scss_1.default.userMenuDroplist, comfortClassName), closeOnPopstate: true, "data-test-id": constants_1.TEST_IDS.userMenu.root, label: t('user'), snapPoints:
|
|
54
|
+
return ((0, jsx_runtime_1.jsx)(list_1.Droplist, { open: open, onOpenChange: setOpen, size: 'm', selection: SELECTION_STUB, pinTop: pinTop, items: menuItems, pinBottom: pinBottom, scroll: !isMobile, trigger: 'click', placement: 'bottom-end', className: (0, classnames_1.default)(styles_module_scss_1.default.userMenuDroplist, comfortClassName), closeOnPopstate: true, "data-test-id": constants_1.TEST_IDS.userMenu.root, label: t('user'), snapPoints: list_1.SNAP_POINTS_PRESET.full, withDividers: false, triggerClassName: styles_module_scss_1.default.userMenuDroplistTrigger, children: trigger }));
|
|
54
55
|
}
|
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.useLogoutItem = useLogoutItem;
|
|
4
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
8
|
const product_1 = require("@cloud-ru/ds-icons/interface/product");
|
|
6
9
|
const react_1 = require("react");
|
|
7
10
|
const locale_1 = require("../../../locale");
|
|
11
|
+
const styles_module_scss_1 = __importDefault(require('../styles.module.css'));
|
|
8
12
|
function useLogoutItem({ onLogout }) {
|
|
9
13
|
const { t } = locale_1.headerLocale.useTranslations();
|
|
10
|
-
return (0, react_1.useMemo)(() =>
|
|
11
|
-
{
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
label: t('logout'),
|
|
15
|
-
},
|
|
16
|
-
onClick: onLogout,
|
|
17
|
-
'data-test-id': 'header__user-menu__logout',
|
|
14
|
+
return (0, react_1.useMemo)(() => ({
|
|
15
|
+
beforeContent: (0, jsx_runtime_1.jsx)(product_1.ExitSVG, {}),
|
|
16
|
+
content: {
|
|
17
|
+
label: t('logout'),
|
|
18
18
|
},
|
|
19
|
-
|
|
19
|
+
className: styles_module_scss_1.default.logoutItem,
|
|
20
|
+
onClick: onLogout,
|
|
21
|
+
'data-test-id': 'header__user-menu__logout',
|
|
22
|
+
}), [onLogout, t]);
|
|
20
23
|
}
|
|
@@ -38,11 +38,11 @@ function useUserMenuItems({ profile, theme, onLogout, topItems = emptyArray_1.EM
|
|
|
38
38
|
}
|
|
39
39
|
pinTop = pinTop.concat(topItems);
|
|
40
40
|
let pinBottom = bottomItems.concat(logoutItem);
|
|
41
|
-
if (isMobile && Boolean(settingItems?.length)) {
|
|
42
|
-
pinBottom = pinBottom.concat([DIVIDER_ITEM, ...settingItems]);
|
|
43
|
-
}
|
|
44
41
|
// В шторке прокручивается всё меню, закреплять части незачем; разделитель над организациями добавляем сами
|
|
45
42
|
if (isMobile) {
|
|
43
|
+
if (settingItems?.length) {
|
|
44
|
+
pinBottom = [...bottomItems, ...settingItems, DIVIDER_ITEM, logoutItem];
|
|
45
|
+
}
|
|
46
46
|
return {
|
|
47
47
|
pinTop: [],
|
|
48
48
|
items: withClose([...pinTop, DIVIDER_ITEM, ...organizationItems, ...pinBottom]),
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
.userMenuDroplistTrigger{
|
|
2
|
+
display:inline-flex;
|
|
3
|
+
}
|
|
4
|
+
|
|
1
5
|
.userMenuDroplist{
|
|
2
|
-
width:
|
|
6
|
+
width:304px;
|
|
3
7
|
}
|
|
4
8
|
|
|
5
9
|
.profileSettingsIcon{
|
|
6
10
|
color:var(--sn-theme-color-neutral-text, var(--sn-brand-color-neutral-40, var(--sn-brand-palette-gray-40, #4a4a4a)));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.logoutItem span,
|
|
14
|
+
.logoutItem svg{
|
|
15
|
+
color:var(--sn-theme-color-red-text, var(--sn-brand-palette-red-40, #a93533));
|
|
7
16
|
}
|
package/dist/cjs/constants.d.ts
CHANGED
package/dist/cjs/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.TEST_IDS = void 0;
|
|
4
4
|
exports.TEST_IDS = {
|
|
5
5
|
headerLayout: {
|
|
6
6
|
root: 'header-layout',
|
|
@@ -29,5 +29,3 @@ exports.TEST_IDS = {
|
|
|
29
29
|
root: 'header__breadcrumbs',
|
|
30
30
|
},
|
|
31
31
|
};
|
|
32
|
-
// Только mobile: в мастере bottomSheet панель открывается на всю высоту экрана.
|
|
33
|
-
exports.BOTTOM_SHEET_FULLSCREEN_SNAP_POINTS = [1];
|
package/dist/cjs/style.css
CHANGED
|
@@ -10,12 +10,8 @@
|
|
|
10
10
|
padding:0 var(--sn-primitive-dimension-4, 4px);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
.
|
|
14
|
-
|
|
15
|
-
display:flex;
|
|
16
|
-
align-items:center;
|
|
17
|
-
box-sizing:border-box;
|
|
18
|
-
height:var(--sn-primitive-dimension-24, 24px);
|
|
13
|
+
.breadcrums{
|
|
14
|
+
padding:0 var(--sn-primitive-dimension-8, 8px);
|
|
19
15
|
}
|
|
20
16
|
|
|
21
17
|
.left{
|
|
@@ -951,10 +947,19 @@
|
|
|
951
947
|
color:var(--sn-theme-color-neutral-onAccent, var(--sn-brand-color-neutral-99, var(--sn-brand-palette-gray-99, #ffffff)));
|
|
952
948
|
background:var(--sn-theme-color-neutral-accent, var(--sn-brand-color-neutral-50, var(--sn-brand-palette-gray-50, #222222)));
|
|
953
949
|
}
|
|
950
|
+
.userMenuDroplistTrigger{
|
|
951
|
+
display:inline-flex;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
954
|
.userMenuDroplist{
|
|
955
|
-
width:
|
|
955
|
+
width:304px;
|
|
956
956
|
}
|
|
957
957
|
|
|
958
958
|
.profileSettingsIcon{
|
|
959
959
|
color:var(--sn-theme-color-neutral-text, var(--sn-brand-color-neutral-40, var(--sn-brand-palette-gray-40, #4a4a4a)));
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
.logoutItem span,
|
|
963
|
+
.logoutItem svg{
|
|
964
|
+
color:var(--sn-theme-color-red-text, var(--sn-brand-palette-red-40, #a93533));
|
|
960
965
|
}
|
|
@@ -7,5 +7,5 @@ import { useMobileLayout } from '../../hooks/useMobileLayout.js';
|
|
|
7
7
|
import styles from './styles.module.css';
|
|
8
8
|
export function HeaderLayout({ menu, logo, select, breadcrumbs, toolbar, className, ...rest }) {
|
|
9
9
|
const isMobile = useMobileLayout();
|
|
10
|
-
return (_jsxs("header", { className: cn(styles.header, className), "data-mobile": isMobile || undefined, ...extractSupportProps({ 'data-test-id': TEST_IDS.headerLayout.root, ...rest }), children: [_jsxs("div", { className: styles.top, children: [_jsxs("div", { className: styles.left, children: [logo && _jsx(_Fragment, { children: logo }), menu && (_jsxs(_Fragment, { children: [_jsx(Divider, { orientation: 'vertical' }), menu, isMobile && _jsx(Divider, { orientation: 'vertical' })] })), !isMobile && select && (_jsxs(_Fragment, { children: [_jsx(Divider, { orientation: 'vertical' }), select] })), !isMobile && breadcrumbs && (_jsxs(_Fragment, { children: [_jsx(Divider, { orientation: 'vertical' }), breadcrumbs] }))] }), _jsx("div", { className: styles.right, children: toolbar })] }), _jsx(Divider, { orientation: 'horizontal' }), isMobile &&
|
|
10
|
+
return (_jsxs("header", { className: cn(styles.header, className), "data-mobile": isMobile || undefined, ...extractSupportProps({ 'data-test-id': TEST_IDS.headerLayout.root, ...rest }), children: [_jsxs("div", { className: styles.top, children: [_jsxs("div", { className: styles.left, children: [logo && _jsx(_Fragment, { children: logo }), menu && (_jsxs(_Fragment, { children: [_jsx(Divider, { orientation: 'vertical' }), menu, isMobile && _jsx(Divider, { orientation: 'vertical' })] })), !isMobile && select && (_jsxs(_Fragment, { children: [_jsx(Divider, { orientation: 'vertical' }), select] })), !isMobile && breadcrumbs && (_jsxs(_Fragment, { children: [_jsx(Divider, { orientation: 'vertical' }), _jsx("div", { className: styles.breadcrums, children: breadcrumbs })] }))] }), _jsx("div", { className: styles.right, children: toolbar })] }), _jsx(Divider, { orientation: 'horizontal' }), isMobile && breadcrumbs && (_jsxs(_Fragment, { children: [_jsx("div", { className: styles.breadcrums, children: breadcrumbs }), _jsx(Divider, { orientation: 'horizontal' })] }))] }));
|
|
11
11
|
}
|
|
@@ -7,12 +7,8 @@
|
|
|
7
7
|
padding:0 var(--sn-primitive-dimension-4, 4px);
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
.
|
|
11
|
-
|
|
12
|
-
display:flex;
|
|
13
|
-
align-items:center;
|
|
14
|
-
box-sizing:border-box;
|
|
15
|
-
height:var(--sn-primitive-dimension-24, 24px);
|
|
10
|
+
.breadcrums{
|
|
11
|
+
padding:0 var(--sn-primitive-dimension-8, 8px);
|
|
16
12
|
}
|
|
17
13
|
|
|
18
14
|
.left{
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Divider } from '@cloud-ru/ds-divider';
|
|
3
|
-
import {
|
|
3
|
+
import { CardNavigation } from '@cloud-ru/ds-uikit-product-card-predefined';
|
|
4
4
|
import { Fragment } from 'react';
|
|
5
5
|
import { TEST_IDS } from '../../../../constants.js';
|
|
6
6
|
import { getLinkEmblem } from '../../utils/index.js';
|
|
7
7
|
import styles from './styles.module.css';
|
|
8
8
|
export function MenuBottom({ settingItems, leftBottom }) {
|
|
9
|
-
return (_jsxs("div", { className: styles.bottom, "data-test-id": TEST_IDS.mainMenu.leftBottom, children: [Boolean(settingItems?.length) && (_jsx("div", { className: styles.bottomItems, "data-test-id": TEST_IDS.mainMenu.leftBottomItems, children: settingItems?.map(item => (_jsxs(Fragment, { children: [item.divider === 'before' && _jsx(Divider, { orientation: 'horizontal', className: styles.bottomDivider }), _jsx(
|
|
9
|
+
return (_jsxs("div", { className: styles.bottom, "data-test-id": TEST_IDS.mainMenu.leftBottom, children: [Boolean(settingItems?.length) && (_jsx("div", { className: styles.bottomItems, "data-test-id": TEST_IDS.mainMenu.leftBottomItems, children: settingItems?.map(item => (_jsxs(Fragment, { children: [item.divider === 'before' && _jsx(Divider, { orientation: 'horizontal', className: styles.bottomDivider }), _jsx(CardNavigation, { ...(item.href ? { href: item.href, as: 'a' } : { as: 'button', type: 'button' }), title: item.label, icon: getLinkEmblem(item), onClick: item.onClick, "data-test-id": `header__drawer-menu__setting-${item.id}` }), item.divider === 'after' && _jsx(Divider, { orientation: 'horizontal', className: styles.bottomDivider })] }, item.id))) })), leftBottom] }));
|
|
10
10
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Divider } from '@cloud-ru/ds-divider';
|
|
3
|
+
import { SNAP_POINTS_PRESET } from '@cloud-ru/ds-list';
|
|
3
4
|
import { useCallback, useMemo } from 'react';
|
|
4
|
-
import {
|
|
5
|
+
import { TEST_IDS } from '../../../../constants.js';
|
|
5
6
|
import { MobileDrawerCustom } from '../../../../mobileOverlays.js';
|
|
6
7
|
import { MainMenuDndContext } from '../../hooks/useMainMenuDnd.js';
|
|
7
8
|
import { useMenuItems } from '../../hooks/useMenuItems.js';
|
|
@@ -32,5 +33,5 @@ export function MenuMobile({ open = false, setOpen, settingItems, platformGroups
|
|
|
32
33
|
const handleClose = useCallback(() => {
|
|
33
34
|
setOpen?.(false);
|
|
34
35
|
}, [setOpen]);
|
|
35
|
-
return (_jsx(MobileDrawerCustom, { open: open, onClose: handleClose, position: 'bottom', className: styles.drawerMobile, swipeEnabled: false, "data-test-id": TEST_IDS.mainMenu.drawerMobile, closeOnPopstate: true, snapPoints:
|
|
36
|
+
return (_jsx(MobileDrawerCustom, { open: open, onClose: handleClose, position: 'bottom', className: styles.drawerMobile, swipeEnabled: false, "data-test-id": TEST_IDS.mainMenu.drawerMobile, closeOnPopstate: true, snapPoints: SNAP_POINTS_PRESET.full, disableMotions: true, children: _jsx(ScrollWithAnimatedStickyPanel, { panel: _jsxs(_Fragment, { children: [_jsx(MenuHeaderBrand, { logo: logo, onClose: handleClose, className: styles.menuHeader, isMobile: true }), _jsx(Divider, { orientation: 'horizontal' })] }), children: _jsxs(MountAnimation, { className: styles.scrollMobile, type: 'fade-slide-up', children: [leftTop, search && _jsx(Search, { ...search, ref: searchRef, isMobile: true }), !isSearching && favorite && _jsx(Favorites, { favorite: favorite, servicesById: servicesById, isMobile: true }), hasSegments && (_jsx(MainMenuDndContext, { children: _jsx(Content, { isMobile: true, searchValue: search && search.value, rightTop: rightTop, favorite: favorite, segments: segments, searchGroups: resultItems, segmentPrefs: segmentPrefs, activeSegmentId: activeSegmentId, onActiveSegmentChange: onActiveSegmentChange, onSegmentOrderChange: onSegmentOrderChange, onSegmentExpandedChange: onSegmentExpandedChange, onSegmentServiceClick: onSegmentServiceClick, loading: loading }) })), !isSearching && hasBottomItems && _jsx(MenuBottom, { settingItems: settingItems, leftBottom: leftBottom })] }) }) }));
|
|
36
37
|
}
|
|
@@ -2,6 +2,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Scroll } from '@cloud-ru/ds-scroll';
|
|
3
3
|
import { useCallback, useRef, useState } from 'react';
|
|
4
4
|
import styles from './styles.module.css';
|
|
5
|
+
// Упругая прокрутка у верхней границы (touch-скролл на мобильных не "упирается" жёстко в 0 —
|
|
6
|
+
// контент можно немного "оттянуть" дальше) даёт scrollTop, не совпадающий с реальным положением
|
|
7
|
+
// контента в этот момент. Диапазон запаса — единицы пикселей; двух хватает с большим запасом.
|
|
8
|
+
const TOP_OVERSCROLL_EPSILON_PX = 2;
|
|
5
9
|
export function ScrollWithAnimatedStickyPanel({ panel, children }) {
|
|
6
10
|
const [positions, setPositions] = useState({ panelTopShift: 0, containerScroll: 0 });
|
|
7
11
|
const [panelHeight, setPanelHeight] = useState(0);
|
|
@@ -14,6 +18,13 @@ export function ScrollWithAnimatedStickyPanel({ panel, children }) {
|
|
|
14
18
|
return;
|
|
15
19
|
const panelHeight = panelRef.current.offsetHeight;
|
|
16
20
|
setPanelHeight(panelHeight);
|
|
21
|
+
// У верхней границы панель всегда полностью видна — не доверяем накопленному diff. Иначе
|
|
22
|
+
// "лишний" ход упругой прокрутки у самого верха читается как скролл вниз и на возврате к
|
|
23
|
+
// началу списка панель может остаться скрытой, хотя пользователь как раз скроллит наверх.
|
|
24
|
+
if (target.scrollTop <= TOP_OVERSCROLL_EPSILON_PX) {
|
|
25
|
+
setPositions({ panelTopShift: 0, containerScroll: target.scrollTop });
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
17
28
|
setPositions(prev => {
|
|
18
29
|
const diff = prev.containerScroll - target.scrollTop;
|
|
19
30
|
return {
|
|
@@ -22,10 +33,11 @@ export function ScrollWithAnimatedStickyPanel({ panel, children }) {
|
|
|
22
33
|
};
|
|
23
34
|
});
|
|
24
35
|
}, []);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
const setPanelRef = useCallback((element) => {
|
|
37
|
+
if (element) {
|
|
38
|
+
setPanelHeight(element.offsetHeight);
|
|
39
|
+
panelRef.current = element;
|
|
40
|
+
}
|
|
41
|
+
}, []);
|
|
42
|
+
return (_jsxs("div", { className: styles.container, style: { '--snack-autohide-panel-height': `${panelHeight}px` }, children: [_jsx(Scroll, { barHideStrategy: 'never', overflow: { x: 'hidden' }, onScroll: handleScroll, children: children }), _jsx("div", { className: styles.panel, ref: setPanelRef, style: { top: positions.panelTopShift }, children: panel })] }));
|
|
31
43
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Avatar } from '@cloud-ru/ds-avatar';
|
|
3
|
-
import { Droplist } from '@cloud-ru/ds-list';
|
|
3
|
+
import { Droplist, SNAP_POINTS_PRESET } from '@cloud-ru/ds-list';
|
|
4
4
|
import { useValueControl } from '@cloud-ru/ds-utils';
|
|
5
5
|
import cn from 'classnames';
|
|
6
|
-
import { useMemo } from 'react';
|
|
7
|
-
import {
|
|
6
|
+
import { useCallback, useMemo } from 'react';
|
|
7
|
+
import { TEST_IDS } from '../../constants.js';
|
|
8
8
|
import { useDesktopComfortClassName } from '../../hooks/useDesktopComfortClassName.js';
|
|
9
9
|
import { useMobileLayout } from '../../hooks/useMobileLayout.js';
|
|
10
10
|
import { headerLocale } from '../../locale/index.js';
|
|
@@ -22,6 +22,9 @@ export function UserMenu({ profile = {}, open: openProp, setOpen: setOpenProp, o
|
|
|
22
22
|
const comfortClassName = useDesktopComfortClassName();
|
|
23
23
|
const [open = false, setOpen] = useValueControl({ value: openProp, onChange: setOpenProp });
|
|
24
24
|
const { fullName = '', inviteCount } = profile;
|
|
25
|
+
const handleClose = useCallback(() => {
|
|
26
|
+
setOpen(false);
|
|
27
|
+
}, [setOpen]);
|
|
25
28
|
const { pinTop, items: menuItems, pinBottom, } = useUserMenuItems({
|
|
26
29
|
isMobile,
|
|
27
30
|
profile,
|
|
@@ -30,9 +33,7 @@ export function UserMenu({ profile = {}, open: openProp, setOpen: setOpenProp, o
|
|
|
30
33
|
organizationItems,
|
|
31
34
|
bottomItems,
|
|
32
35
|
settingItems,
|
|
33
|
-
onClose:
|
|
34
|
-
setOpen(false);
|
|
35
|
-
},
|
|
36
|
+
onClose: handleClose,
|
|
36
37
|
onLogout,
|
|
37
38
|
});
|
|
38
39
|
const trigger = useMemo(() => (_jsx(HeaderButton, { tooltip: { tip: triggerTooltip }, isMobile: isMobile, onClick: () => {
|
|
@@ -44,5 +45,5 @@ export function UserMenu({ profile = {}, open: openProp, setOpen: setOpenProp, o
|
|
|
44
45
|
appearance: 'primary',
|
|
45
46
|
}
|
|
46
47
|
: undefined, "data-test-id": TEST_IDS.userMenu.button, icon: _jsx(Avatar, { appearance: 'red', size: 's', name: fullName, showTwoSymbols: true }), "data-pressed": open })), [fullName, inviteCount, onClick, open, setOpen, isMobile, triggerTooltip]);
|
|
47
|
-
return (_jsx(Droplist, { open: open, onOpenChange: setOpen, size: 'm', selection: SELECTION_STUB, pinTop: pinTop, items: menuItems, pinBottom: pinBottom, scroll: !isMobile, trigger: 'click', placement: 'bottom-end', className: cn(styles.userMenuDroplist, comfortClassName), closeOnPopstate: true, "data-test-id": TEST_IDS.userMenu.root, label: t('user'), snapPoints:
|
|
48
|
+
return (_jsx(Droplist, { open: open, onOpenChange: setOpen, size: 'm', selection: SELECTION_STUB, pinTop: pinTop, items: menuItems, pinBottom: pinBottom, scroll: !isMobile, trigger: 'click', placement: 'bottom-end', className: cn(styles.userMenuDroplist, comfortClassName), closeOnPopstate: true, "data-test-id": TEST_IDS.userMenu.root, label: t('user'), snapPoints: SNAP_POINTS_PRESET.full, withDividers: false, triggerClassName: styles.userMenuDroplistTrigger, children: trigger }));
|
|
48
49
|
}
|
|
@@ -2,16 +2,16 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { ExitSVG } from '@cloud-ru/ds-icons/interface/product';
|
|
3
3
|
import { useMemo } from 'react';
|
|
4
4
|
import { headerLocale } from '../../../locale/index.js';
|
|
5
|
+
import styles from '../styles.module.css';
|
|
5
6
|
export function useLogoutItem({ onLogout }) {
|
|
6
7
|
const { t } = headerLocale.useTranslations();
|
|
7
|
-
return useMemo(() =>
|
|
8
|
-
{
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
label: t('logout'),
|
|
12
|
-
},
|
|
13
|
-
onClick: onLogout,
|
|
14
|
-
'data-test-id': 'header__user-menu__logout',
|
|
8
|
+
return useMemo(() => ({
|
|
9
|
+
beforeContent: _jsx(ExitSVG, {}),
|
|
10
|
+
content: {
|
|
11
|
+
label: t('logout'),
|
|
15
12
|
},
|
|
16
|
-
|
|
13
|
+
className: styles.logoutItem,
|
|
14
|
+
onClick: onLogout,
|
|
15
|
+
'data-test-id': 'header__user-menu__logout',
|
|
16
|
+
}), [onLogout, t]);
|
|
17
17
|
}
|
|
@@ -35,11 +35,11 @@ export function useUserMenuItems({ profile, theme, onLogout, topItems = EMPTY_AR
|
|
|
35
35
|
}
|
|
36
36
|
pinTop = pinTop.concat(topItems);
|
|
37
37
|
let pinBottom = bottomItems.concat(logoutItem);
|
|
38
|
-
if (isMobile && Boolean(settingItems?.length)) {
|
|
39
|
-
pinBottom = pinBottom.concat([DIVIDER_ITEM, ...settingItems]);
|
|
40
|
-
}
|
|
41
38
|
// В шторке прокручивается всё меню, закреплять части незачем; разделитель над организациями добавляем сами
|
|
42
39
|
if (isMobile) {
|
|
40
|
+
if (settingItems?.length) {
|
|
41
|
+
pinBottom = [...bottomItems, ...settingItems, DIVIDER_ITEM, logoutItem];
|
|
42
|
+
}
|
|
43
43
|
return {
|
|
44
44
|
pinTop: [],
|
|
45
45
|
items: withClose([...pinTop, DIVIDER_ITEM, ...organizationItems, ...pinBottom]),
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
.userMenuDroplistTrigger{
|
|
2
|
+
display:inline-flex;
|
|
3
|
+
}
|
|
4
|
+
|
|
1
5
|
.userMenuDroplist{
|
|
2
|
-
width:
|
|
6
|
+
width:304px;
|
|
3
7
|
}
|
|
4
8
|
|
|
5
9
|
.profileSettingsIcon{
|
|
6
10
|
color:var(--sn-theme-color-neutral-text, var(--sn-brand-color-neutral-40, var(--sn-brand-palette-gray-40, #4a4a4a)));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.logoutItem span,
|
|
14
|
+
.logoutItem svg{
|
|
15
|
+
color:var(--sn-theme-color-red-text, var(--sn-brand-palette-red-40, #a93533));
|
|
7
16
|
}
|
package/dist/esm/constants.d.ts
CHANGED
package/dist/esm/constants.js
CHANGED
package/dist/esm/style.css
CHANGED
|
@@ -10,12 +10,8 @@
|
|
|
10
10
|
padding:0 var(--sn-primitive-dimension-4, 4px);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
.
|
|
14
|
-
|
|
15
|
-
display:flex;
|
|
16
|
-
align-items:center;
|
|
17
|
-
box-sizing:border-box;
|
|
18
|
-
height:var(--sn-primitive-dimension-24, 24px);
|
|
13
|
+
.breadcrums{
|
|
14
|
+
padding:0 var(--sn-primitive-dimension-8, 8px);
|
|
19
15
|
}
|
|
20
16
|
|
|
21
17
|
.left{
|
|
@@ -951,10 +947,19 @@
|
|
|
951
947
|
color:var(--sn-theme-color-neutral-onAccent, var(--sn-brand-color-neutral-99, var(--sn-brand-palette-gray-99, #ffffff)));
|
|
952
948
|
background:var(--sn-theme-color-neutral-accent, var(--sn-brand-color-neutral-50, var(--sn-brand-palette-gray-50, #222222)));
|
|
953
949
|
}
|
|
950
|
+
.userMenuDroplistTrigger{
|
|
951
|
+
display:inline-flex;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
954
|
.userMenuDroplist{
|
|
955
|
-
width:
|
|
955
|
+
width:304px;
|
|
956
956
|
}
|
|
957
957
|
|
|
958
958
|
.profileSettingsIcon{
|
|
959
959
|
color:var(--sn-theme-color-neutral-text, var(--sn-brand-color-neutral-40, var(--sn-brand-palette-gray-40, #4a4a4a)));
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
.logoutItem span,
|
|
963
|
+
.logoutItem svg{
|
|
964
|
+
color:var(--sn-theme-color-red-text, var(--sn-brand-palette-red-40, #a93533));
|
|
960
965
|
}
|