Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
172de88
refactor: use global variable for items height
Dec 30, 2025
5a5ae06
feat(AsideHeader): add isCompactMode prop infrastructure
Jan 5, 2026
a2c7473
feat(AsideHeader): add compact item height support
Jan 5, 2026
f760686
feat(AsideHeader): add compact collapsed width (40px)
Jan 5, 2026
8ad898e
feat(AsideHeader): add compact margin-inline (6px)
Jan 5, 2026
cbc1025
feat(AsideHeader): add compact border-radius and header divider
Jan 5, 2026
85a35e6
docs(AsideHeader): add isCompactMode documentation and story
Jan 5, 2026
5b00a07
fix: items height
Jan 9, 2026
4b045f6
refactor: extract getCollapsedWidth utility function
Jan 9, 2026
f4be484
feat: add compact divider icon for 40px navigation width
Jan 9, 2026
7f04de3
refactor: move compact-mode CSS variables to aside container
Jan 9, 2026
b87ae37
feat: add compact mode support for CollapseButton and update stories
Jan 9, 2026
9527df7
feat: use css variable to set --_--item-collapsed-radius
Jan 12, 2026
1a1003e
feat: added new test case for navigation with compact mode
Jan 12, 2026
71bf7b4
test: renamed test files with collapsed mode
Jan 12, 2026
02a0ebd
fix: wrong margin between items
Jan 12, 2026
1dd2afc
feat: updated font size and line height in navigation
Jan 12, 2026
f790efb
feat: adjust logo size by compact mode
Jan 12, 2026
de62acc
test: update screenshots
Jan 12, 2026
ec91703
feat: remove unused code
Jan 12, 2026
ce49ac0
fix: gaps calculation
Jan 13, 2026
3c92749
fix: css issue with icon margin
Jan 13, 2026
1423e0b
refactor: renamed some test cases and stories
Jan 13, 2026
deabf72
refactor: remove commented commented code
Jan 13, 2026
4da2228
refactor: renamed some variables for better readability
Jan 13, 2026
e25324b
fix: add default value for logo place when variable --_--item-height …
Jan 13, 2026
95c1a63
test: updated screenshot with default logo width
Jan 13, 2026
5ade186
feat: get back logo size for footer
Jan 14, 2026
f78d6cc
feat: use correct margins in logo component
Jan 14, 2026
c823d98
test: updated screenshots
Jan 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions assets/icons/divider-collapsed-compact.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 22 additions & 13 deletions src/components/AsideHeader/AsideHeader.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ $block: '.#{variables.$ns}aside-header';

#{$block} {
$class: &;
--gn-aside-header-min-width: 56px;
--gn-aside-header-min-width: #{variables.$aside-header-min-width};

--_--item-height: #{variables.$item-height};
--_--item-margin-inline: #{variables.$item-margin-inline};
--gn-aside-header-item-expanded-radius: #{variables.$item-expanded-radius};
--gn-aside-header-header-divider-height: #{variables.$header-divider-height};

--_--item-icon-background-size: 36px;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this variable no longer needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I use the --_--item-height instead

--_--background-color: var(--g-color-base-background);
--_--decoration-collapsed-background-color: var(--g-color-base-warning-light);
--_--decoration-expanded-background-color: var(--g-color-base-warning-light);
Expand Down Expand Up @@ -102,6 +106,15 @@ $block: '.#{variables.$ns}aside-header';

z-index: -1;
}

&_compact-mode {
--_--item-height: #{variables.$item-height-compact};
--_--item-margin-inline: #{variables.$item-margin-inline-compact};
--_--item-collapsed-radius: #{variables.$item-expanded-radius-compact};
--gn-aside-header-item-expanded-radius: #{variables.$item-expanded-radius-compact};
--gn-aside-header-header-divider-height: #{variables.$header-divider-height-compact};
--gn-aside-header-min-width: #{variables.$aside-header-min-width-compact};
}
}

&_collapsed &__aside {
Expand Down Expand Up @@ -142,15 +155,13 @@ $block: '.#{variables.$ns}aside-header';
}

&__header {
--gn-aside-header-header-divider-height: 29px;

position: relative;
z-index: 1;
flex: none;
box-sizing: border-box;
width: calc(100%);
padding-top: 8px;
padding-bottom: 22px;
padding-bottom: 25px;
background-color: var(--gn-aside-top-decoration-background-color);

#{$class}__header-divider {
Expand Down Expand Up @@ -222,7 +233,8 @@ $block: '.#{variables.$ns}aside-header';
display: flex;
align-items: center;
justify-content: space-between;
margin-inline: 10px;
margin-inline: var(--_--item-margin-inline);
margin-bottom: 2px;

&_without-logo {
padding-bottom: var(--g-spacing-2);
Expand All @@ -232,24 +244,21 @@ $block: '.#{variables.$ns}aside-header';
}

&__logo-button &__logo-icon-place {
height: var(
--gn-aside-header-item-icon-background-size,
var(--_--item-icon-background-size)
);
width: var(--_--item-icon-background-size);
height: var(--_--item-height);
width: var(--_--item-height);
}

&__menu-items {
flex-grow: 1;
}

&__menu-item:not(:has([data-type='action'])) {
margin-inline: 10px;
margin-inline: var(--_--item-margin-inline);
}

&__footer {
flex-shrink: 0;
margin: var(--g-spacing-2) 10px;
margin: var(--g-spacing-2) var(--_--item-margin-inline);
display: flex;
flex-direction: column;
background-color: var(--gn-aside-bottom-background-color);
Expand Down
5 changes: 3 additions & 2 deletions src/components/AsideHeader/AsideHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import {PageLayoutAside} from './components/PageLayout/PageLayoutAside';
import {AsideHeaderProps} from './types';

export const AsideHeader = React.forwardRef<HTMLDivElement, AsideHeaderProps>(
({pinned, className, topAlert, ...props}, ref) => {
({pinned, className, topAlert, isCompactMode, ...props}, ref) => {
return (
<PageLayout
pinned={pinned}
onChangePinned={props.onChangePinned}
className={className}
topAlert={topAlert}
isCompactMode={isCompactMode}
>
<PageLayoutAside ref={ref} {...props} />
<PageLayoutAside ref={ref} {...props} isCompactMode={isCompactMode} />
<PageLayout.Content renderContent={props.renderContent} />
</PageLayout>
);
Expand Down
1 change: 1 addition & 0 deletions src/components/AsideHeader/README-ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ export const Aside: FC = () => {
| expandTitle | Заголовок `CollapseButton` для разворачивания элемента навигации. | `string` | `"Развернуть"` `"Expand"` |
| headerDecoration | Цвет фона верхнего блока с элементами логотипа и подзаголовка. | `boolean` | `false` |
| hideCollapseButton | Скрывает `CollapseButton`. Для установки дефолтного состояния элемента навигации используйте свойство `pinned`. | `boolean` | `false` |
| isCompactMode | При `true` элементы меню используют компактную высоту. | `boolean` | `false` |
| logo | Контейнер логотипа, включающий иконку с заголовком и обрабатывающий клики. | [`Logo`](./../Logo/Readme.md#logo) | |
| menuItems | Элементы в среднем блоке навигации. | `Array<AsideHeaderItem>` | `[]` |
| menuMoreTitle | Дополнительный заголовок для `menuItems`, если элементы не помещаются. | `string` | `"Ещё"` `"More"` |
Expand Down
1 change: 1 addition & 0 deletions src/components/AsideHeader/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ export const Aside: FC = () => {
| expandTitle | `CollapseButton` title for expanding navigation | `string` | `"Развернуть"` `"Expand"` |
| headerDecoration | Color background of the top section with logo and subheader items | `boolean` | `false` |
| hideCollapseButton | Hiding `CollapseButton`. Use `pinned` prop for setting default navigation state | `boolean` | `false` |
| isCompactMode | When `true`, menu items use compact height | `boolean` | `false` |
| logo | Logo container includes icon, title, handling clicks | [`Logo`](https://github.com/gravity-ui/navigation/blob/main/src/components/Logo/Readme.md#logo) | |
| menuItems | Items in the navigation middle section | `Array<AsideHeaderItem>` | `[]` |
| menuMoreTitle | Additional element title of menuItems if elements don't fit | `string` | `"Ещё"` `"More"` |
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
13 changes: 9 additions & 4 deletions src/components/AsideHeader/__stories__/AsideHeader.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ export default {
const ShowcaseTemplate: StoryFn = (args) => <AsideHeaderShowcase {...args} />;
export const Showcase = ShowcaseTemplate.bind({});

const CompactTemplate: StoryFn = (args) => <AsideHeaderShowcase {...args} />;
export const Compact = CompactTemplate.bind({});
Compact.args = {
const CollapsedNavigationTemplate: StoryFn = (args) => <AsideHeaderShowcase {...args} />;
export const CollapsedNavigation = CollapsedNavigationTemplate.bind({});
CollapsedNavigation.args = {
initialPinned: false,
hideCollapseButton: true,
};
Expand Down Expand Up @@ -334,7 +334,7 @@ const GroupedMenuCollapsibleTemplate: StoryFn = (args) => {
const [currentMenuGroups, setCurrentMenuGroups] = React.useState(menuGroupsWithIcons);

return (
<PageLayout pinned={pinned} onChangePinned={setPinned}>
<PageLayout pinned={pinned} onChangePinned={setPinned} isCompactMode={args.isCompactMode}>
<PageLayoutAside
headerDecoration
logo={DEFAULT_LOGO}
Expand Down Expand Up @@ -372,6 +372,11 @@ GroupedMenuCollapsible.args = {
initialPinned: true,
};

export const CompactItemSizing = GroupedMenuCollapsibleTemplate.bind({});
CompactItemSizing.args = {
isCompactMode: true,
};

const CustomThemesWithNewColorsTemplate: StoryFn = (args) => {
return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export interface AsideHeaderShowcaseProps {
customBackgroundClassName?: string;
headerDecoration?: boolean;
hideCollapseButton?: boolean;
isCompactMode?: boolean;
externalMenuItems?: AsideHeaderProps['menuItems'];
externalMenuGroups?: AsideHeaderProps['menuGroups'];
}
Expand All @@ -55,6 +56,7 @@ export const AsideHeaderShowcase: React.FC<React.PropsWithChildren<AsideHeaderSh
customBackgroundClassName,
headerDecoration,
hideCollapseButton,
isCompactMode,
externalMenuItems,
externalMenuGroups,
children,
Expand Down Expand Up @@ -154,6 +156,7 @@ export const AsideHeaderShowcase: React.FC<React.PropsWithChildren<AsideHeaderSh
]}
pinned={pinned}
hideCollapseButton={hideCollapseButton}
isCompactMode={isCompactMode}
multipleTooltip={multipleTooltip}
openModalSubscriber={openModalSubscriber}
topAlert={topAlert}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function getAsideHeaderWrapper(
props: AsideHeaderProps = {
logo: {
icon: logoIcon,
iconSize: 24,
iconSize: 32,
text: 'My Service',
'aria-label': 'My Service',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,17 @@ test.describe('AsideHeader', () => {
await expectScreenshot();
});

test('render story: <Compact>', async ({mount, expectScreenshot}) => {
await mount(<AsideHeaderStories.Compact />, undefined, {
test('render story: <CollapsedNavigation>', async ({mount, expectScreenshot}) => {
await mount(<AsideHeaderStories.CollapsedNavigation />, undefined, {
width: 1200,
height: 720,
});

await expectScreenshot();
});

test('render story: <CompactItemSizing>', async ({mount, expectScreenshot}) => {
await mount(<AsideHeaderStories.CompactItemSizing />, undefined, {
width: 1200,
height: 720,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,11 @@
height: 100%;
padding: var(--g-spacing-4) var(--g-spacing-6);
box-sizing: border-box;
--gn-aside-header-item-expanded-radius: 6px;
--gn-aside-header-item-expanded-radius: #{variables.$item-expanded-radius};
--_--item-height: #{variables.$item-height};

&__content {
overflow: auto;
flex: 1;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why these styles were removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because they're unused

&__discoverable-feature-wrapper {
display: flex;
}

&__menu-group {
width: 100%;
margin-inline: 10px;

&:not(:last-child) {
padding-bottom: var(--g-spacing-2);
border-bottom: 1px solid var(--g-color-line-generic);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ const b = createBlock('collapse-button', styles);

interface CollapseButtonProps {
className?: string;
isCompactMode?: boolean;
}

export const CollapseButton = ({className}: CollapseButtonProps) => {
export const CollapseButton = ({className, isCompactMode}: CollapseButtonProps) => {
const {pinned, onChangePinned} = useAsideHeaderContext();
const {expandTitle, collapseTitle, collapseButtonWrapper} = useAsideHeaderInnerContext();

Expand All @@ -32,7 +33,7 @@ export const CollapseButton = ({className}: CollapseButtonProps) => {
const defaultButton = (
<Button
view="flat-secondary"
size="l"
size={isCompactMode ? 'm' : 'l'}
className={b({collapsed: !pinned}, className)}
onClick={onCollapseButtonClick}
aria-label={buttonTitle}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ $block: '.#{variables.$ns}composite-bar';
#{$block} {
$class: &;

--gn-aside-header-item-expanded-radius: 6px;

flex: 1 1 auto;
width: 100%;
min-height: 40px;
Expand Down Expand Up @@ -85,9 +83,8 @@ $block: '.#{variables.$ns}composite-bar';
}
}

&__menu-group-header,
&__menu-group-item {
height: 36px;
&__menu-group-header {
height: var(--_--item-height);
}

&__menu-group-item {
Expand Down Expand Up @@ -145,6 +142,6 @@ $block: '.#{variables.$ns}composite-bar';
}

&__menu-item[data-type='action'] {
margin-inline: 10px;
margin-inline: var(--_--item-margin-inline);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import React, {FC, ReactNode, useCallback, useContext, useRef, useState} from 'r
import {ChevronRight} from '@gravity-ui/icons';
import {List, ListSortParams} from '@gravity-ui/uikit';

import {ASIDE_HEADER_COMPACT_WIDTH} from '../../../constants';
import {createBlock} from '../../../utils/cn';
import {getCollapsedWidth} from '../../../utils/getCollapsedWidth';
import {AsideHeaderItem, MenuItemsWithGroups} from '../../types';
import {UNGROUPED_ID} from '../AllPagesPanel/constants';

Expand Down Expand Up @@ -36,6 +36,8 @@ type CompositeBarProps = {
menuItemClassName?: string;
editMode?: boolean;
onToggleGroupCollapsed?: (groupId: string) => void;
/** When `true`, menu items use compact height. */
isCompactMode?: boolean;
};

type CompositeBarViewProps = CompositeBarProps & {
Expand All @@ -51,6 +53,8 @@ type CompositeBarViewProps = CompositeBarProps & {
onSecondLevelSortEnd?: (
groupIndex: number,
) => (params: {oldIndex: number; newIndex: number}) => void;
/** When `true`, menu items use compact height. */
isCompactMode?: boolean;
};

export const CompositeBarView: FC<CompositeBarViewProps> = ({
Expand All @@ -70,6 +74,7 @@ export const CompositeBarView: FC<CompositeBarViewProps> = ({
onToggleMenuItemVisibility,
onFirstLevelSortEnd,
onSecondLevelSortEnd,
isCompactMode,
}) => {
const ref = useRef<List<AsideHeaderItem>>(null);
const tooltipRef = useRef<HTMLDivElement>(null);
Expand All @@ -96,6 +101,8 @@ export const CompositeBarView: FC<CompositeBarViewProps> = ({
};
}, [multipleTooltip, multipleTooltipActive, setMultipleTooltipContextValue]);

const collapsedWidth = getCollapsedWidth(isCompactMode);

const onTooltipMouseEnter = useCallback(
(e: {clientX: number}) => {
if (
Expand All @@ -104,7 +111,7 @@ export const CompositeBarView: FC<CompositeBarViewProps> = ({
!multipleTooltipActive &&
document.hasFocus() &&
activeIndex !== lastClickedItemIndex &&
e.clientX <= ASIDE_HEADER_COMPACT_WIDTH
e.clientX <= collapsedWidth
) {
setMultipleTooltipContextValue?.({
active: true,
Expand All @@ -117,6 +124,7 @@ export const CompositeBarView: FC<CompositeBarViewProps> = ({
multipleTooltipActive,
activeIndex,
lastClickedItemIndex,
collapsedWidth,
setMultipleTooltipContextValue,
],
);
Expand Down Expand Up @@ -250,8 +258,8 @@ export const CompositeBarView: FC<CompositeBarViewProps> = ({
ref={ref}
items={items}
selectedItemIndex={type === 'menu' ? getSelectedItemIndex(items) : undefined}
itemHeight={getItemHeight}
itemsHeight={getItemsHeight}
itemHeight={(item) => getItemHeight(item, isCompactMode)}
itemsHeight={(items) => getItemsHeight(items, isCompactMode)}
itemClassName={b('root-menu-item', {collapsed: !isExpanded}, menuItemClassName)}
virtualized={false}
filterable={false}
Expand Down Expand Up @@ -339,8 +347,10 @@ export const CompositeBarView: FC<CompositeBarViewProps> = ({
edit: enableSorting,
collapsed: !isExpanded,
})}
itemHeight={getItemHeight}
itemsHeight={getItemsHeight}
itemHeight={(item) => getItemHeight(item, isCompactMode)}
itemsHeight={(items) =>
getItemsHeight(items, isCompactMode)
}
renderItem={(
nestedItem,
_isNestedItemActive,
Expand Down Expand Up @@ -404,6 +414,7 @@ export const CompositeBar: FC<CompositeBarProps> = ({
className,
menuItemClassName,
editMode = false,
isCompactMode,
}) => {
const visibleItems = items
?.filter((item) => !item.hidden)
Expand Down Expand Up @@ -432,6 +443,7 @@ export const CompositeBar: FC<CompositeBarProps> = ({
multipleTooltip={multipleTooltip}
onToggleGroupCollapsed={onToggleGroupCollapsed}
editMode={editMode}
isCompactMode={isCompactMode}
/>
</div>
);
Expand All @@ -445,6 +457,7 @@ export const CompositeBar: FC<CompositeBarProps> = ({
items={visibleItems}
onItemClick={onItemClick}
editMode={editMode}
isCompactMode={isCompactMode}
/>
</div>
);
Expand Down
Loading