Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0e0dfa3
chore(deps): update @consta/uikit version
ShavrinAleksei Oct 31, 2025
2d47690
chore(package.json): add test script
ShavrinAleksei Oct 31, 2025
d0c9b5a
refactor(Navbar): remove unused NavbarDrawer
ShavrinAleksei Oct 31, 2025
ac5554c
feat(Navbar): add types for controlled subMenu
ShavrinAleksei Oct 31, 2025
02f4177
feat(Navbar): add passing of subMenu props
ShavrinAleksei Oct 31, 2025
7cf28f5
feat(Navbar): implement controlled subMenu state in NavbarItem
ShavrinAleksei Oct 31, 2025
d852ee6
chore(NavbarArrow): add tests for arrow component
ShavrinAleksei Oct 31, 2025
376eef6
chore(NavbarRailItem): add tests for rail item component
ShavrinAleksei Oct 31, 2025
e2f03c5
chore(NavbarRail): add tests for rail container component
ShavrinAleksei Oct 31, 2025
9829a40
chore(NavbarItem): add tests for NavbarItem component
ShavrinAleksei Oct 31, 2025
291adb3
chore(Navbar): add tests for Navbar component
ShavrinAleksei Oct 31, 2025
2cc2221
chore(jest.config.js): configure test setup
ShavrinAleksei Oct 31, 2025
375693c
docs(Navbar): add description and example for new subMenu props
ShavrinAleksei Oct 31, 2025
0a39bbd
refactor(Navbar): rename onItemSubMenuToggle to onSubMenuToggle
ShavrinAleksei Nov 5, 2025
d440d27
refactor(Navbar): rename onItemSubMenuToggle to onSubMenuToggle
ShavrinAleksei Nov 5, 2025
9406a1f
refactor(NavbarItem): implement controlled subMenu with onSubMenuToggle
ShavrinAleksei Nov 5, 2025
0293424
chore(Navbar): update tests for onSubMenuToggle rename and remove red…
ShavrinAleksei Nov 5, 2025
62ded2b
docs(Navbar): update API reference for subMenu toggle changes
ShavrinAleksei Nov 5, 2025
66b8930
docs(Navbar): update API reference for subMenu toggle types
ShavrinAleksei Nov 5, 2025
be3fbf0
chore(deps): update
gizeasy Nov 6, 2025
4b791ae
fix(Navbar): update onSubMenuToggle callback signature
ShavrinAleksei Nov 6, 2025
6542f7e
fix(NavbarItem): update onSubMenuToggle usage and reorder effects
ShavrinAleksei Nov 6, 2025
15658fd
chore(Navbar): update tests for new onSubMenuToggle signature
ShavrinAleksei Nov 6, 2025
43bac82
docs(Navbar): update docs for new onSubMenuToggle signature
ShavrinAleksei Nov 6, 2025
4af80fe
fix(Navbar): change getItemSubMenuOpen return type from boolean | und…
ShavrinAleksei Nov 7, 2025
b9e7ab3
docs(Navbar): update getItemSubMenuOpen type documentation
ShavrinAleksei Nov 7, 2025
f9c9aa6
feat(Navbar): add controlled submenu example
ShavrinAleksei Nov 7, 2025
91c6760
docs(Navbar): add interactive controlled submenu example
ShavrinAleksei Nov 7, 2025
45c6d7f
feat(Navbar): add CSS styles for controlled submenu example
ShavrinAleksei Nov 7, 2025
cdd6a97
refactor(Navbar): update controlled example to use CSS classes
ShavrinAleksei Nov 7, 2025
37e902b
docs(Navbar): add interactive tabs for controlled submenu example
ShavrinAleksei Nov 7, 2025
4d6cea9
docs(Navbar): edit menu
gizeasy Nov 10, 2025
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
9 changes: 8 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@ module.exports = {
'\\.css$': '<rootDir>/__mocks__/styleMock.js',
'##/(.*)$': '<rootDir>/src/$1',
},
coveragePathIgnorePatterns: ['/node_modules/', '/coverage/', '/types/'],
transform: {
'^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
},
testMatch: ['**/*.test.{ts,tsx}'],
modulePathIgnorePatterns: ['<rootDir>/dist/'],
coveragePathIgnorePatterns: ['/node_modules/', '/coverage/', '/types/'],
transformIgnorePatterns: [
// Транспайлим библиотеки на es-модулях в commonjs-модули
`<rootDir>/node_modules/(?!(@consta)/).+\\.(js|jsx|ts|tsx)`,
],
collectCoverageFrom: ['**/*.{ts,tsx}', '!**/*.stories.tsx'],
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['./jest.setup.ts'],
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"format:svg": "prettier --write '**/*.svg' --parser html",
"pre-push": "yarn run tsc-dry-run",
"pre-commit": "yarn run lint-staged",
"test": "yarn tsc-dry-run",
"test": "yarn tsc-dry-run && yarn unit",
"unit": "jest",
"unit:watch": "jest --watch",
"unit:clear": "jest --clearCache",
Expand Down Expand Up @@ -51,7 +51,7 @@
"@bem-react/classname": "^1.6.0",
"@bem-react/classnames": "^1.3.10",
"@consta/icons": "^1.1.1",
"@consta/uikit": "^5.22.0",
"@consta/uikit": "^5.26.0",
"date-fns": "^2.30.0"
},
"config": {
Expand Down Expand Up @@ -124,7 +124,7 @@
"camelcase": "^6.2.1",
"case-sensitive-paths-webpack-plugin": "^2.4.0",
"commitizen": "^4.2.5",
"compute-scroll-into-view": "^1.0.17",
"compute-scroll-into-view": "^3.1.1",
"cross-env": "^7.0.3",
"css-loader": "^6.5.1",
"css-minimizer-webpack-plugin": "^3.4.1",
Expand Down Expand Up @@ -170,7 +170,7 @@
"react-dev-utils": "^12.0.0",
"react-dom": "^18.0.0",
"react-dropzone": "^14.2.3",
"react-imask": "^7.2.1",
"react-imask": "^7.6.1",
"react-refresh": "^0.11.0",
"react-test-renderer": "^18.0.0",
"react-textarea-autosize": "^8.5.3",
Expand Down
6 changes: 5 additions & 1 deletion src/components/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
NavbarProps,
} from './types';

const cnNavbar = cnCanary('Navbar');
export const cnNavbar = cnCanary('Navbar');

const NavbarRender = (props: NavbarProps, ref: React.Ref<HTMLDivElement>) => {
const {
Expand All @@ -37,6 +37,8 @@ const NavbarRender = (props: NavbarProps, ref: React.Ref<HTMLDivElement>) => {
form = defaultNavbarPropForm,
getItemSubMenu,
getItemStatus,
getItemSubMenuOpen,
onSubMenuToggle,
sortGroup,
className,
...otherProps
Expand Down Expand Up @@ -81,6 +83,8 @@ const NavbarRender = (props: NavbarProps, ref: React.Ref<HTMLDivElement>) => {
getItemRightSide={getItemRightSide}
getItemSubMenu={getItemSubMenu}
getItemStatus={getItemStatus}
getItemSubMenuOpen={getItemSubMenuOpen}
onSubMenuToggle={onSubMenuToggle}
form={form}
/>
</React.Fragment>
Expand Down
159 changes: 159 additions & 0 deletions src/components/Navbar/NavbarArrow/__tests__/NavbarArrow.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { fireEvent, render, screen } from '@testing-library/react';
import React from 'react';

import { NavbarArrow } from '../NavbarArrow';

const defaultProps = {
open: false,
onClick: jest.fn(),
};

const renderNavbarArrow = (props = {}) => {
return render(<NavbarArrow {...defaultProps} {...props} />);
};

describe('Компонент NavbarArrow', () => {
describe('Базовый рендеринг', () => {
it('должен рендериться без ошибок', () => {
expect(() => renderNavbarArrow()).not.toThrow();
});

it('должен отображать кнопку', () => {
renderNavbarArrow();
expect(screen.getByRole('button')).toBeInTheDocument();
});

it('должен отображать иконку стрелки', () => {
renderNavbarArrow();
const icon = document.querySelector('.IconArrowDown');
expect(icon).toBeInTheDocument();
});
});

describe('Пропсы и состояние', () => {
it('должен применять правильные пропсы к Button', () => {
renderNavbarArrow();

const button = screen.getByRole('button');

expect(button).toHaveClass('Button_size_xs');
expect(button).toHaveClass('Button_view_clear');
expect(button).toHaveClass('Button_onlyIcon');
expect(button).toHaveAttribute('tabindex', '-1');
});

it('должен передавать open в AnimateIconSwitcherProvider', () => {
const { rerender } = renderNavbarArrow({ open: false });

let iconContainer = document.querySelector('.icons--AnimateIconBase');
expect(iconContainer).toHaveStyle(
'--animate-icon-direction: rotate(0deg)',
);

rerender(<NavbarArrow {...defaultProps} open />);
iconContainer = document.querySelector('.icons--AnimateIconBase');
expect(iconContainer).toHaveStyle(
'--animate-icon-direction: rotate(180deg)',
);
});

it('должен корректно работать с разными состояниями open', () => {
const { rerender } = renderNavbarArrow({ open: false });

expect(document.querySelector('.icons--AnimateIconBase')).toHaveStyle(
'--animate-icon-direction: rotate(0deg)',
);

rerender(<NavbarArrow {...defaultProps} open />);
expect(document.querySelector('.icons--AnimateIconBase')).toHaveStyle(
'--animate-icon-direction: rotate(180deg)',
);

rerender(<NavbarArrow {...defaultProps} open={false} />);
expect(document.querySelector('.icons--AnimateIconBase')).toHaveStyle(
'--animate-icon-direction: rotate(0deg)',
);
});
});

describe('Взаимодействие', () => {
it('должен вызывать onClick при клике на кнопку', () => {
const onClick = jest.fn();
renderNavbarArrow({ onClick });

fireEvent.click(screen.getByRole('button'));
expect(onClick).toHaveBeenCalledTimes(1);
});

it('должен корректно обрабатывать multiple clicks', () => {
const onClick = jest.fn();
renderNavbarArrow({ onClick });

const button = screen.getByRole('button');

fireEvent.click(button);
fireEvent.click(button);
fireEvent.click(button);

expect(onClick).toHaveBeenCalledTimes(3);
});
});

describe('Визуальное состояние', () => {
it('должен иметь правильные стили для размера xs', () => {
renderNavbarArrow();

const button = screen.getByRole('button');
const icon = document.querySelector('.icons--Icon');

expect(button).toHaveClass('Button_size_xs');
expect(icon).toHaveClass('icons--Icon_size_xs');
});

it('должен иметь прозрачный вид (view="clear")', () => {
renderNavbarArrow();

const button = screen.getByRole('button');
expect(button).toHaveClass('Button_view_clear');
});

it('должен быть только с иконкой (onlyIcon)', () => {
renderNavbarArrow();

const button = screen.getByRole('button');
expect(button).toHaveClass('Button_onlyIcon');
});
});

describe('Accessibility', () => {
it('должен иметь tabIndex -1', () => {
renderNavbarArrow();

const button = screen.getByRole('button');
expect(button).toHaveAttribute('tabindex', '-1');
});

it('должен быть доступен для кликов', () => {
renderNavbarArrow();

const button = screen.getByRole('button');
expect(button).not.toBeDisabled();
});
});

describe('Интеграция с анимацией', () => {
it('должен использовать AnimateIconSwitcherProvider', () => {
renderNavbarArrow();

const provider = document.querySelector('.icons--AnimateIconBase');
expect(provider).toBeInTheDocument();
});

it('должен использовать HOC withAnimateSwitcherHOC для иконки', () => {
renderNavbarArrow();

const arrowIcon = document.querySelector('.IconArrowDown');
expect(arrowIcon).toBeInTheDocument();
});
});
});
92 changes: 0 additions & 92 deletions src/components/Navbar/NavbarItem/NavbarDrawer.tsx

This file was deleted.

Loading