refactor(App): enhance vertical sidebar layout and styling for improved usability and consistency
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 3m19s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 3m19s
This commit is contained in:
@@ -54,6 +54,28 @@
|
||||
.navbar-vertical > .container-fluid {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100%;
|
||||
}
|
||||
.navbar-vertical .collapse.navbar-collapse {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
.navbar-vertical .collapse .navbar-nav.pt-lg-3 {
|
||||
flex: 1 1 auto;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.navbar-vertical .navbar-sidebar-footer {
|
||||
flex-shrink: 0;
|
||||
border-top-color: rgba(255, 255, 255, 0.1) !important;
|
||||
}
|
||||
.navbar-vertical .navbar-sidebar-footer .nav-link {
|
||||
padding-left: 0.75rem;
|
||||
padding-right: 0.75rem;
|
||||
}
|
||||
/* Стрелка только у пунктов с подменю (dropdown-toggle), не у обычных ссылок и не у бренда */
|
||||
.navbar-vertical .nav-link:not(.dropdown-toggle)::after {
|
||||
|
||||
+61
-96
@@ -469,11 +469,71 @@ function MainLayout() {
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
{/* Кнопки внизу сайдбара: язык, раскладка, тема, горячие клавиши, настройки */}
|
||||
<div className="navbar-sidebar-footer navbar-nav flex-column border-top pt-2 mt-auto">
|
||||
<div className="nav-item dropdown">
|
||||
<a
|
||||
href="#"
|
||||
className="nav-link dropdown-toggle px-3 py-2"
|
||||
data-bs-toggle="dropdown"
|
||||
onClick={(e) => e.preventDefault()}
|
||||
title="Язык"
|
||||
>
|
||||
<span className="badge">{lang.toUpperCase()}</span>
|
||||
</a>
|
||||
<div className="dropdown-menu dropdown-menu-end">
|
||||
<a href="#" className={`dropdown-item ${lang === 'ru' ? 'active' : ''}`} onClick={(e) => { e.preventDefault(); setLang('ru'); }}>Русский</a>
|
||||
<a href="#" className={`dropdown-item ${lang === 'en' ? 'active' : ''}`} onClick={(e) => { e.preventDefault(); setLang('en'); }}>English</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="nav-item dropdown">
|
||||
<a
|
||||
href="#"
|
||||
className="nav-link dropdown-toggle px-3 py-2"
|
||||
data-bs-toggle="dropdown"
|
||||
onClick={(e) => e.preventDefault()}
|
||||
title={t('layoutSidebar')}
|
||||
>
|
||||
{layout === LAYOUT_FLUID ? <IconLayoutSidebarLeftExpand size={20} /> : <IconLayoutNavbar size={20} />}
|
||||
</a>
|
||||
<div className="dropdown-menu dropdown-menu-end">
|
||||
<a href="#" className={`dropdown-item d-flex align-items-center ${layout === LAYOUT_FLUID ? 'active' : ''}`} onClick={(e) => { e.preventDefault(); setLayout(LAYOUT_FLUID); }}>
|
||||
<IconLayoutSidebarLeftExpand className="me-2" size={18} /> {t('layoutSidebar')}
|
||||
</a>
|
||||
<a href="#" className={`dropdown-item d-flex align-items-center ${layout === LAYOUT_HORIZONTAL ? 'active' : ''}`} onClick={(e) => { e.preventDefault(); setLayout(LAYOUT_HORIZONTAL); }}>
|
||||
<IconLayoutNavbar className="me-2" size={18} /> {t('layoutHorizontal')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="nav-item dropdown">
|
||||
<a
|
||||
href="#"
|
||||
className="nav-link dropdown-toggle px-3 py-2"
|
||||
data-bs-toggle="dropdown"
|
||||
onClick={(e) => e.preventDefault()}
|
||||
title={t('light') + ' / ' + t('dark')}
|
||||
>
|
||||
{theme === 'dark' ? '🌙' : '☀️'}
|
||||
</a>
|
||||
<div className="dropdown-menu dropdown-menu-end">
|
||||
<a href="#" className={`dropdown-item ${theme === 'light' ? 'active' : ''}`} onClick={(e) => { e.preventDefault(); setTheme('light'); }}>☀️ {t('light')}</a>
|
||||
<a href="#" className={`dropdown-item ${theme === 'dark' ? 'active' : ''}`} onClick={(e) => { e.preventDefault(); setTheme('dark'); }}>🌙 {t('dark')}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="nav-item">
|
||||
<KeyboardShortcutsButton className="nav-link px-3 py-2" title="Горячие клавиши" />
|
||||
</div>
|
||||
<div className="nav-item">
|
||||
<a href="#" className="nav-link px-3 py-2" onClick={(e) => { e.preventDefault(); setSettingsOpen(true); }} title="Настройки">
|
||||
<IconSettings size={20} />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* Верхний навбар (как в Tabler fluid vertical) */}
|
||||
{/* Верхний навбар (только тогглер меню на мобильных; кнопки — внизу сайдбара) */}
|
||||
<header className="navbar navbar-expand-md d-print-none">
|
||||
<div className="container-fluid">
|
||||
<button
|
||||
@@ -486,101 +546,6 @@ function MainLayout() {
|
||||
>
|
||||
<IconMenu2 />
|
||||
</button>
|
||||
<div className="navbar-nav flex-row order-md-last flex-grow-1 justify-content-end">
|
||||
<div className="nav-item dropdown">
|
||||
<a
|
||||
href="#"
|
||||
className="nav-link px-2 dropdown-toggle"
|
||||
data-bs-toggle="dropdown"
|
||||
onClick={(e) => e.preventDefault()}
|
||||
>
|
||||
<span className="badge">{lang.toUpperCase()}</span>
|
||||
</a>
|
||||
<div className="dropdown-menu dropdown-menu-end">
|
||||
<a
|
||||
href="#"
|
||||
className={`dropdown-item ${lang === 'ru' ? 'active' : ''}`}
|
||||
onClick={(e) => { e.preventDefault(); setLang('ru'); }}
|
||||
>
|
||||
Русский
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className={`dropdown-item ${lang === 'en' ? 'active' : ''}`}
|
||||
onClick={(e) => { e.preventDefault(); setLang('en'); }}
|
||||
>
|
||||
English
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="nav-item dropdown">
|
||||
<a
|
||||
href="#"
|
||||
className="nav-link px-2 dropdown-toggle"
|
||||
data-bs-toggle="dropdown"
|
||||
onClick={(e) => e.preventDefault()}
|
||||
>
|
||||
{layout === LAYOUT_FLUID ? <IconLayoutSidebarLeftExpand size={20} /> : <IconLayoutNavbar size={20} />}
|
||||
</a>
|
||||
<div className="dropdown-menu dropdown-menu-end">
|
||||
<a
|
||||
href="#"
|
||||
className={`dropdown-item d-flex align-items-center ${layout === LAYOUT_FLUID ? 'active' : ''}`}
|
||||
onClick={(e) => { e.preventDefault(); setLayout(LAYOUT_FLUID); }}
|
||||
>
|
||||
<IconLayoutSidebarLeftExpand className="me-2" size={18} />
|
||||
{t('layoutSidebar')}
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className={`dropdown-item d-flex align-items-center ${layout === LAYOUT_HORIZONTAL ? 'active' : ''}`}
|
||||
onClick={(e) => { e.preventDefault(); setLayout(LAYOUT_HORIZONTAL); }}
|
||||
>
|
||||
<IconLayoutNavbar className="me-2" size={18} />
|
||||
{t('layoutHorizontal')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="nav-item dropdown">
|
||||
<a
|
||||
href="#"
|
||||
className="nav-link px-2 dropdown-toggle"
|
||||
data-bs-toggle="dropdown"
|
||||
onClick={(e) => e.preventDefault()}
|
||||
>
|
||||
{theme === 'dark' ? '🌙' : '☀️'}
|
||||
</a>
|
||||
<div className="dropdown-menu dropdown-menu-end">
|
||||
<a
|
||||
href="#"
|
||||
className={`dropdown-item ${theme === 'light' ? 'active' : ''}`}
|
||||
onClick={(e) => { e.preventDefault(); setTheme('light'); }}
|
||||
>
|
||||
☀️ {t('light')}
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
className={`dropdown-item ${theme === 'dark' ? 'active' : ''}`}
|
||||
onClick={(e) => { e.preventDefault(); setTheme('dark'); }}
|
||||
>
|
||||
🌙 {t('dark')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="nav-item">
|
||||
<KeyboardShortcutsButton className="nav-link px-2" />
|
||||
</div>
|
||||
<div className="nav-item">
|
||||
<a
|
||||
href="#"
|
||||
className="nav-link px-2"
|
||||
onClick={(e) => { e.preventDefault(); setSettingsOpen(true); }}
|
||||
title="Настройки"
|
||||
>
|
||||
<IconSettings size={20} />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user