mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-08-29 00:41:25 +08:00
feat(layout): update sidebar layout and add tooltip for navigation badges
This commit is contained in:
@@ -7,13 +7,14 @@ import {
|
||||
useLayoutEffect,
|
||||
useRef,
|
||||
useState,
|
||||
type MouseEvent as ReactMouseEvent,
|
||||
} from 'react';
|
||||
import { NavLink, useLocation } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { PageTransition } from '@/components/common/PageTransition';
|
||||
import { MainRoutes } from '@/router/MainRoutes';
|
||||
import { pluginsApi } from '@/services/api';
|
||||
import { authFilesApi, pluginsApi } from '@/services/api';
|
||||
import {
|
||||
IconSidebarAuthFiles,
|
||||
IconSidebarConfig,
|
||||
@@ -69,6 +70,7 @@ interface SidebarNavLinkItem {
|
||||
metaKey?: string;
|
||||
label?: string;
|
||||
meta?: string;
|
||||
badge?: number;
|
||||
icon: ReactNode;
|
||||
}
|
||||
|
||||
@@ -317,6 +319,12 @@ export function MainLayout() {
|
||||
|
||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
|
||||
const [authFilesCount, setAuthFilesCount] = useState<number | null>(null);
|
||||
const [railTooltip, setRailTooltip] = useState<{
|
||||
label: string;
|
||||
meta?: string;
|
||||
top: number;
|
||||
} | null>(null);
|
||||
const [languageMenuOpen, setLanguageMenuOpen] = useState(false);
|
||||
const [themeMenuOpen, setThemeMenuOpen] = useState(false);
|
||||
const [pluginResources, setPluginResources] = useState<PluginResourceEntry[]>([]);
|
||||
@@ -449,9 +457,24 @@ export function MainLayout() {
|
||||
}
|
||||
}, [connectionStatus, supportsPlugin]);
|
||||
|
||||
const loadAuthFilesCount = useCallback(async () => {
|
||||
if (connectionStatus !== 'connected') {
|
||||
setAuthFilesCount(null);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await authFilesApi.list();
|
||||
setAuthFilesCount(Array.isArray(response?.files) ? response.files.length : null);
|
||||
} catch {
|
||||
setAuthFilesCount(null);
|
||||
}
|
||||
}, [connectionStatus]);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = window.setTimeout(() => {
|
||||
void loadPluginResources();
|
||||
void loadAuthFilesCount();
|
||||
}, 0);
|
||||
|
||||
window.addEventListener(PLUGIN_RESOURCES_REFRESH_EVENT, loadPluginResources);
|
||||
@@ -460,7 +483,7 @@ export function MainLayout() {
|
||||
window.clearTimeout(timer);
|
||||
window.removeEventListener(PLUGIN_RESOURCES_REFRESH_EVENT, loadPluginResources);
|
||||
};
|
||||
}, [apiBase, loadPluginResources]);
|
||||
}, [apiBase, loadPluginResources, loadAuthFilesCount]);
|
||||
|
||||
const pluginResourceGroups = pluginResources.reduce<
|
||||
Array<{ pluginID: string; pluginTitle: string; entries: PluginResourceEntry[] }>
|
||||
@@ -550,6 +573,7 @@ export function MainLayout() {
|
||||
path: '/auth-files',
|
||||
labelKey: 'nav.auth_files',
|
||||
metaKey: 'nav_meta.auth_files',
|
||||
badge: authFilesCount ?? undefined,
|
||||
icon: sidebarIcons.authFiles,
|
||||
},
|
||||
{
|
||||
@@ -668,6 +692,7 @@ export function MainLayout() {
|
||||
const results = await Promise.allSettled([
|
||||
fetchConfig(true),
|
||||
loadPluginResources(),
|
||||
loadAuthFilesCount(),
|
||||
triggerHeaderRefresh(),
|
||||
]);
|
||||
const rejected = results.find((result) => result.status === 'rejected');
|
||||
@@ -696,6 +721,22 @@ export function MainLayout() {
|
||||
});
|
||||
}, []);
|
||||
|
||||
const showRailTooltip = useCallback(
|
||||
(event: ReactMouseEvent<HTMLElement>, label: string, meta?: string) => {
|
||||
const rect = event.currentTarget.getBoundingClientRect();
|
||||
setRailTooltip({ label, meta, top: rect.top + rect.height / 2 });
|
||||
},
|
||||
[]
|
||||
);
|
||||
const hideRailTooltip = useCallback(() => setRailTooltip(null), []);
|
||||
|
||||
const renderNavBadge = (badge?: number) =>
|
||||
typeof badge === 'number' && badge > 0 ? (
|
||||
<span className="nav-badge" aria-hidden="true">
|
||||
{badge}
|
||||
</span>
|
||||
) : null;
|
||||
|
||||
const renderNavLink = (item: SidebarNavLinkItem, className = 'nav-item') => {
|
||||
const itemLabel = item.label ?? (item.labelKey ? t(item.labelKey) : '');
|
||||
const itemMeta = item.meta ?? (item.metaKey ? t(item.metaKey) : '');
|
||||
@@ -705,15 +746,26 @@ export function MainLayout() {
|
||||
key={item.path}
|
||||
to={item.path}
|
||||
className={({ isActive }) => `${className} ${isActive ? 'active' : ''}`}
|
||||
onClick={() => setSidebarOpen(false)}
|
||||
title={showSidebarLabels ? undefined : itemLabel}
|
||||
onClick={() => {
|
||||
setSidebarOpen(false);
|
||||
hideRailTooltip();
|
||||
}}
|
||||
aria-label={showSidebarLabels ? undefined : itemLabel}
|
||||
onMouseEnter={
|
||||
showSidebarLabels ? undefined : (event) => showRailTooltip(event, itemLabel, itemMeta)
|
||||
}
|
||||
onMouseLeave={showSidebarLabels ? undefined : hideRailTooltip}
|
||||
>
|
||||
<span className="nav-icon">{item.icon}</span>
|
||||
{showSidebarLabels && (
|
||||
<span className="nav-text">
|
||||
<span className="nav-label">{itemLabel}</span>
|
||||
{itemMeta ? <span className="nav-meta">{itemMeta}</span> : null}
|
||||
</span>
|
||||
{showSidebarLabels ? (
|
||||
<>
|
||||
<span className="nav-text">
|
||||
<span className="nav-label">{itemLabel}</span>
|
||||
</span>
|
||||
{renderNavBadge(item.badge)}
|
||||
</>
|
||||
) : (
|
||||
renderNavBadge(item.badge)
|
||||
)}
|
||||
</NavLink>
|
||||
);
|
||||
@@ -735,15 +787,18 @@ export function MainLayout() {
|
||||
isOpen ? 'open' : ''
|
||||
}`}
|
||||
onClick={() => togglePluginResourceDrawer(item.id)}
|
||||
title={showSidebarLabels ? undefined : item.label}
|
||||
aria-label={showSidebarLabels ? undefined : item.label}
|
||||
aria-expanded={isOpen}
|
||||
onMouseEnter={
|
||||
showSidebarLabels ? undefined : (event) => showRailTooltip(event, item.label, item.meta)
|
||||
}
|
||||
onMouseLeave={showSidebarLabels ? undefined : hideRailTooltip}
|
||||
>
|
||||
<span className="nav-icon">{item.icon}</span>
|
||||
{showSidebarLabels && (
|
||||
<>
|
||||
<span className="nav-text">
|
||||
<span className="nav-label">{item.label}</span>
|
||||
{item.meta ? <span className="nav-meta">{item.meta}</span> : null}
|
||||
</span>
|
||||
<span className="nav-drawer-caret" aria-hidden="true">
|
||||
<IconChevronDown size={14} />
|
||||
@@ -776,17 +831,12 @@ export function MainLayout() {
|
||||
<button
|
||||
type="button"
|
||||
className="sidebar-toggle-floating"
|
||||
onClick={() => setSidebarCollapsed((prev) => !prev)}
|
||||
title={
|
||||
sidebarCollapsed
|
||||
? t('sidebar.expand', { defaultValue: '展开' })
|
||||
: t('sidebar.collapse', { defaultValue: '收起' })
|
||||
}
|
||||
aria-label={
|
||||
sidebarCollapsed
|
||||
? t('sidebar.expand', { defaultValue: '展开' })
|
||||
: t('sidebar.collapse', { defaultValue: '收起' })
|
||||
}
|
||||
onClick={() => {
|
||||
hideRailTooltip();
|
||||
setSidebarCollapsed((prev) => !prev);
|
||||
}}
|
||||
title={sidebarCollapsed ? t('sidebar.expand') : t('sidebar.collapse')}
|
||||
aria-label={sidebarCollapsed ? t('sidebar.expand') : t('sidebar.collapse')}
|
||||
>
|
||||
{sidebarCollapsed ? headerIcons.chevronRight : headerIcons.chevronLeft}
|
||||
</button>
|
||||
@@ -939,9 +989,16 @@ export function MainLayout() {
|
||||
<aside
|
||||
className={`sidebar ${sidebarOpen ? 'open' : ''} ${sidebarCollapsed ? 'collapsed' : ''}`}
|
||||
>
|
||||
<div className="sidebar-brand" title={fullBrandName}>
|
||||
<img src={INLINE_LOGO_JPEG} alt="CPAMC logo" className="sidebar-brand-logo" />
|
||||
{showSidebarLabels && <span className="sidebar-brand-title">{abbrBrandName}</span>}
|
||||
<div className="sidebar-header">
|
||||
<div className="sidebar-brand" title={fullBrandName}>
|
||||
<img src={INLINE_LOGO_JPEG} alt="CPAMC logo" className="sidebar-brand-logo" />
|
||||
{showSidebarLabels && (
|
||||
<span className="sidebar-brand-text">
|
||||
<span className="sidebar-brand-title">{abbrBrandName}</span>
|
||||
<span className="sidebar-brand-subtitle">{t('sidebar.subtitle')}</span>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="nav-section">
|
||||
@@ -959,8 +1016,18 @@ export function MainLayout() {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
</aside>
|
||||
|
||||
{!showSidebarLabels && railTooltip && (
|
||||
<div className="nav-tooltip" role="tooltip" style={{ top: railTooltip.top }}>
|
||||
<span className="nav-tooltip-label">{railTooltip.label}</span>
|
||||
{railTooltip.meta ? (
|
||||
<span className="nav-tooltip-meta">{railTooltip.meta}</span>
|
||||
) : null}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
className={`content${isLogsPage ? ' content-logs' : ''}${
|
||||
isPluginResourcePage ? ' content-plugin-resource' : ''
|
||||
|
||||
@@ -1294,7 +1294,10 @@
|
||||
},
|
||||
"sidebar": {
|
||||
"toggle_expand": "Expand sidebar",
|
||||
"toggle_collapse": "Collapse sidebar"
|
||||
"toggle_collapse": "Collapse sidebar",
|
||||
"expand": "Expand",
|
||||
"collapse": "Collapse",
|
||||
"subtitle": "CLI Proxy API Console"
|
||||
},
|
||||
"footer": {
|
||||
"api_version": "CLI Proxy API Version",
|
||||
|
||||
@@ -1272,7 +1272,10 @@
|
||||
},
|
||||
"sidebar": {
|
||||
"toggle_expand": "Развернуть боковую панель",
|
||||
"toggle_collapse": "Свернуть боковую панель"
|
||||
"toggle_collapse": "Свернуть боковую панель",
|
||||
"expand": "Развернуть",
|
||||
"collapse": "Свернуть",
|
||||
"subtitle": "Консоль управления CLI Proxy API"
|
||||
},
|
||||
"footer": {
|
||||
"api_version": "Версия CLI Proxy API",
|
||||
|
||||
@@ -1294,7 +1294,10 @@
|
||||
},
|
||||
"sidebar": {
|
||||
"toggle_expand": "展开侧边栏",
|
||||
"toggle_collapse": "收起侧边栏"
|
||||
"toggle_collapse": "收起侧边栏",
|
||||
"expand": "展开",
|
||||
"collapse": "收起",
|
||||
"subtitle": "CLI Proxy API 管理控制台"
|
||||
},
|
||||
"footer": {
|
||||
"api_version": "CLI Proxy API 版本",
|
||||
|
||||
@@ -1320,7 +1320,10 @@
|
||||
},
|
||||
"sidebar": {
|
||||
"toggle_expand": "展開側邊欄",
|
||||
"toggle_collapse": "收起側邊欄"
|
||||
"toggle_collapse": "收起側邊欄",
|
||||
"expand": "展開",
|
||||
"collapse": "收起",
|
||||
"subtitle": "CLI Proxy API 管理控制台"
|
||||
},
|
||||
"footer": {
|
||||
"api_version": "CLI Proxy API 版本",
|
||||
|
||||
+158
-74
@@ -3,8 +3,8 @@
|
||||
:root {
|
||||
--header-height: 80px;
|
||||
--shell-gutter: 24px;
|
||||
--sidebar-panel-width: 256px;
|
||||
--sidebar-collapsed-width: 68px;
|
||||
--sidebar-panel-width: 216px;
|
||||
--sidebar-collapsed-width: 60px;
|
||||
--sidebar-active-width: var(--sidebar-panel-width);
|
||||
--sidebar-gap: 0px;
|
||||
--floating-control-size: 38px;
|
||||
@@ -395,10 +395,10 @@
|
||||
z-index: $z-dropdown - 1;
|
||||
width: var(--sidebar-panel-width);
|
||||
height: 100vh;
|
||||
padding: 18px 14px;
|
||||
padding: 14px 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $spacing-md;
|
||||
gap: $spacing-sm;
|
||||
flex-shrink: 0;
|
||||
overflow-y: auto;
|
||||
background: var(--bg-primary);
|
||||
@@ -422,19 +422,40 @@
|
||||
|
||||
&.collapsed {
|
||||
width: var(--sidebar-collapsed-width);
|
||||
padding: 18px 10px;
|
||||
padding: 14px 8px;
|
||||
|
||||
.sidebar-brand {
|
||||
.sidebar-header {
|
||||
justify-content: center;
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.sidebar-brand {
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
position: relative;
|
||||
justify-content: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.nav-badge {
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
right: 1px;
|
||||
margin-left: 0;
|
||||
min-width: 15px;
|
||||
height: 15px;
|
||||
padding: 0 4px;
|
||||
border-radius: $radius-full;
|
||||
font-size: 9px;
|
||||
color: #fff;
|
||||
background: var(--error-color);
|
||||
box-shadow: 0 0 0 2px var(--bg-primary);
|
||||
}
|
||||
|
||||
.nav-group-label {
|
||||
display: none;
|
||||
}
|
||||
@@ -454,41 +475,67 @@
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-height: 36px;
|
||||
padding: 2px 2px 10px;
|
||||
margin-bottom: 2px;
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--border-color) 60%, transparent);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.sidebar-brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
min-height: 42px;
|
||||
padding: 4px 10px 14px;
|
||||
margin-bottom: 4px;
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--border-color) 60%, transparent);
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
padding: 0 6px;
|
||||
color: var(--text-primary);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.sidebar-brand-logo {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
object-fit: contain;
|
||||
border-radius: 8px;
|
||||
border-radius: 7px;
|
||||
box-shadow: none;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.sidebar-brand-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
line-height: 1.15;
|
||||
}
|
||||
|
||||
.sidebar-brand-title {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
color: var(--text-primary);
|
||||
font-size: 18px;
|
||||
font-size: 15px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.sidebar-brand-subtitle {
|
||||
margin-top: 1px;
|
||||
overflow: hidden;
|
||||
font-size: 10.5px;
|
||||
font-weight: 500;
|
||||
color: color-mix(in srgb, var(--text-primary) 46%, transparent);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.nav-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
gap: 10px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@@ -504,8 +551,8 @@
|
||||
}
|
||||
|
||||
.nav-group-label {
|
||||
padding: 0 12px 4px;
|
||||
font-size: 10.5px;
|
||||
padding: 0 10px 2px;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
@@ -548,22 +595,23 @@
|
||||
.nav-sub-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
margin-left: 21px;
|
||||
gap: 2px;
|
||||
margin-left: 18px;
|
||||
padding-left: 10px;
|
||||
border-left: 1px solid color-mix(in srgb, var(--border-color) 72%, transparent);
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
padding: 9px 12px;
|
||||
border-radius: 11px;
|
||||
padding: 6px 10px;
|
||||
border-radius: 9px;
|
||||
border: 1px solid transparent;
|
||||
color: var(--text-primary);
|
||||
font-weight: 650;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $spacing-sm;
|
||||
gap: 10px;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background $transition-fast,
|
||||
@@ -572,35 +620,26 @@
|
||||
transform $transition-fast;
|
||||
|
||||
.nav-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
color: currentColor;
|
||||
opacity: 0.96;
|
||||
border-radius: 8px;
|
||||
background:
|
||||
linear-gradient(180deg, rgb(255 255 255 / 0.12), rgb(255 255 255 / 0)),
|
||||
color-mix(in srgb, var(--bg-secondary) 84%, transparent);
|
||||
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--border-primary) 82%, transparent);
|
||||
transition:
|
||||
background $transition-fast,
|
||||
box-shadow $transition-fast,
|
||||
color $transition-fast;
|
||||
color: color-mix(in srgb, var(--text-primary) 58%, transparent);
|
||||
transition: color $transition-fast;
|
||||
|
||||
svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 5px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 4px;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
@@ -619,14 +658,21 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.nav-meta {
|
||||
margin-top: 2px;
|
||||
font-size: 11.5px;
|
||||
font-weight: 500;
|
||||
color: color-mix(in srgb, var(--text-primary) 50%, transparent);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
.nav-badge {
|
||||
min-width: 18px;
|
||||
height: 18px;
|
||||
margin-left: auto;
|
||||
padding: 0 5px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
border-radius: $radius-full;
|
||||
background: color-mix(in srgb, var(--text-primary) 9%, transparent);
|
||||
color: color-mix(in srgb, var(--text-primary) 58%, transparent);
|
||||
font-size: 10.5px;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@@ -635,14 +681,7 @@
|
||||
transform: translateX(1px);
|
||||
|
||||
.nav-icon {
|
||||
background:
|
||||
linear-gradient(180deg, rgb(255 255 255 / 0.16), rgb(255 255 255 / 0)),
|
||||
color-mix(in srgb, var(--bg-primary) 88%, transparent);
|
||||
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--border-hover) 86%, transparent);
|
||||
}
|
||||
|
||||
.nav-meta {
|
||||
color: color-mix(in srgb, var(--text-primary) 62%, transparent);
|
||||
color: color-mix(in srgb, var(--text-primary) 82%, transparent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,28 +693,19 @@
|
||||
|
||||
.nav-icon {
|
||||
color: var(--primary-active);
|
||||
background:
|
||||
linear-gradient(180deg, rgb(255 255 255 / 0.18), rgb(255 255 255 / 0)),
|
||||
color-mix(in srgb, var(--primary-color) 14%, var(--bg-primary));
|
||||
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary-color) 24%, transparent);
|
||||
}
|
||||
|
||||
.nav-meta {
|
||||
color: color-mix(in srgb, var(--text-primary) 68%, transparent);
|
||||
}
|
||||
}
|
||||
|
||||
&.nav-sub-item {
|
||||
min-height: 34px;
|
||||
padding: 7px 10px;
|
||||
border-radius: 9px;
|
||||
font-size: 13px;
|
||||
min-height: 30px;
|
||||
padding: 5px 10px;
|
||||
border-radius: 8px;
|
||||
font-size: 12.5px;
|
||||
font-weight: 600;
|
||||
|
||||
.nav-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 6px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -689,6 +719,48 @@
|
||||
}
|
||||
}
|
||||
|
||||
.nav-tooltip {
|
||||
position: fixed;
|
||||
left: calc(var(--sidebar-collapsed-width) + 12px);
|
||||
z-index: $z-dropdown + 2;
|
||||
transform: translateY(-50%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 3px;
|
||||
max-width: 260px;
|
||||
padding: 9px 12px;
|
||||
border-radius: 10px;
|
||||
background: #24211c;
|
||||
color: #f6f4f1;
|
||||
box-shadow: 0 14px 36px rgb(0 0 0 / 0.32);
|
||||
pointer-events: none;
|
||||
animation: nav-tooltip-in $transition-fast ease-out;
|
||||
|
||||
.nav-tooltip-label {
|
||||
font-size: 13px;
|
||||
font-weight: 650;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.nav-tooltip-meta {
|
||||
font-size: 11.5px;
|
||||
color: rgb(246 244 241 / 0.6);
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes nav-tooltip-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-50%) translateX(-4px);
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(-50%) translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
@@ -857,12 +929,24 @@
|
||||
|
||||
&.collapsed {
|
||||
width: var(--sidebar-panel-width);
|
||||
padding: 18px 14px;
|
||||
padding: 14px 10px;
|
||||
|
||||
.sidebar-brand,
|
||||
.nav-item {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.nav-badge {
|
||||
position: static;
|
||||
min-width: 18px;
|
||||
height: 18px;
|
||||
margin-left: auto;
|
||||
padding: 0 5px;
|
||||
font-size: 10.5px;
|
||||
color: color-mix(in srgb, var(--text-primary) 58%, transparent);
|
||||
background: color-mix(in srgb, var(--text-primary) 9%, transparent);
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user