/
DevDenzo
/
ERP
Обзор
Документация
Войти
/
DevDenzo
/
ERP
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/app-core/Navigation/components/ButtonStretchMenu/ButtonStretchMenu.jsx
128 строк
6 KB
Denis Sklyarskij
Инициализирован репозиторий
14 янв 2026, 23:32
14 янв 2026, 23:32
1df3d47
Код
Авторство
О чём код?
/** * Презентационный компонент кнопки растягивания меню (ButtonStretchMenu) * * Отрисовывает интерактивную кнопку для управления шириной вертикального меню. * При клике меняет ширину меню и иконку (ChevronRight ↔ ChevronDown). * * Особенности: * - использует React.memo для оптимизации рендеринга; * - монтируется через ReactDOM.createPortal в указанный DOM‑узел; * - динамически применяет стили в зависимости от состояния isStretched. * * Зависимости: * - React (memo) — оптимизация производительности; * - classnames — формирование CSS‑классов; * - react-dom — работа с порталами; * - prop-types — валидация пропсов; * - react-bootstrap-icons — иконки интерфейса; * - стили _button-stretch-menu.less — оформление компонента. */ // Подключаем библиотеку React для работы с виртуальным DOM import React, { memo, useContext } from 'react'; // Подключаем библиотеку для динамического формирования CSS‑классов import classNames from 'classnames'; // Подключаем ReactDOM для использования порталов (createPortal) import ReactDOM from 'react-dom'; // Подключаем библиотеку для валидации пропсов компонента import PropTypes from 'prop-types'; // Импортируем контекст передачи текущей цветовой темы между компонентами (светлая/тёмная/серая) import { ThemesContext } from "../../../../contexts/ThemesContext.js"; // Импортируем иконки из react-bootstrap-icons import { ChevronRight, ChevronDown } from 'react-bootstrap-icons'; // Подключаем стили для кнопки растягивания меню import './styles/_button-stretch-menu.less'; /** * Компонент кнопки растягивания меню * @param {Object} props — Пропсы компонента * @param {boolean} props.isStretched — Флаг состояния растянутого меню (true — растянуто, false — сжато) * @param {Function} props.handlerChangeWidthVerticalMenuNav — Обработчик клика для изменения ширины меню * @param {Object} props.startWidthToggleButtonStyles — Начальные стили ширины кнопки * @param {Object} props.stretchedWidthToggleButtonStyles — Стили ширины кнопки в растянутом состоянии * @returns {JSX.Element} Кнопка, отрендеренная в портал */ const ButtonStretchMenu = memo(({ isStretched, handlerChangeWidthVerticalMenuNav}) => { // Получаем DOM‑узел для портала по ID (место вставки кнопки в разметку) const navbarToggleButtonContainer = document.getElementById('navbar-toggle-button-container'); // Получаем состояние текущей цветовой темы const { loadedThemes } = useContext(ThemesContext); // Монтируем компонент в указанный DOM‑узел через портал return ReactDOM.createPortal( <div className={classNames('button-stretch-menu-container')}> <button type="button" className={classNames( 'btn', 'btn-light', 'button-stretch-menu', { 'button-stretch-menu--white': loadedThemes['white'], 'button-stretch-menu--gray': loadedThemes['gray'], 'button-stretch-menu--dark': loadedThemes['dark'] } )} // Динамически применяем стили ширины в зависимости от состояния style={{ marginLeft: (isStretched ? "175px": "") }} > {/* Иконка для сжатого состояния (стрелка вправо) */} {!isStretched && ( <span className={classNames( 'button-stretch-menu__icon', 'button-stretch-menu__icon--right' )} onClick={handlerChangeWidthVerticalMenuNav} // Обработчик клика > <ChevronRight size={18} /> </span> )} {/* Иконка для растянутого состояния (стрелка вниз) */} {isStretched && ( <span className={classNames( 'button-stretch-menu__icon', 'button-stretch-menu__icon--down' )} > <ChevronDown size={18} /> </span> )} </button> </div>, navbarToggleButtonContainer // Целевой DOM‑узел для портала ); }); /** * Валидация пропсов компонента ButtonStretchMenu * * Гарантирует корректность передаваемых данных: * - isStretched: обязательный булев флаг; * - handlerChangeWidthVerticalMenuNav: обязательная функция; * - startWidthToggleButtonStyles: объект стилей (необязательный); * - stretchedWidthToggleButtonStyles: объект стилей (необязательный). */ ButtonStretchMenu.propTypes = { isStretched: PropTypes.bool.isRequired, handlerChangeWidthVerticalMenuNav: PropTypes.func.isRequired }; /** * Экспорт компонента по умолчанию * * Позволяет импортировать компонент как: * import ButtonStretchMenu from './ButtonStretchMenu.jsx'; */ export default ButtonStretchMenu;