fix: unify shell theme and responsive workspace

This commit is contained in:
ochenstarik 2026-09-21 23:43:42 +07:00
parent 45179d2a2c
commit 24ef652275
4 changed files with 46 additions and 24 deletions

View file

@ -22,7 +22,7 @@ export const AppShell: React.FC = () => {
activeLocation, activeLocation,
} = useDemoStore(); } = useDemoStore();
const { isMobile, isTablet, isDesktop } = useResponsive(); const { width, isMobile, isTablet, isDesktop } = useResponsive();
const profile = getActiveProfile(); const profile = getActiveProfile();
const location = useLocation(); const location = useLocation();
const isCommunicationsPage = location.pathname.startsWith('/communications'); const isCommunicationsPage = location.pathname.startsWith('/communications');
@ -36,7 +36,9 @@ export const AppShell: React.FC = () => {
dark: 'graphite-forest-dark', dark: 'graphite-forest-dark',
}[theme]; }[theme];
document.documentElement.setAttribute('data-krona-theme', kronaTheme); document.documentElement.setAttribute('data-krona-theme', kronaTheme);
}, [theme]); document.documentElement.setAttribute('data-omni-theme', kronaTheme);
document.documentElement.setAttribute('data-omni-density', isMobile ? 'touch' : 'workspace');
}, [theme, isMobile]);
// Layout resolution: // Layout resolution:
// 1. Real screen size is paramount: // 1. Real screen size is paramount:
@ -78,7 +80,11 @@ export const AppShell: React.FC = () => {
{/* Main Shell Layout */} {/* Main Shell Layout */}
<div className="flex-1 flex overflow-hidden w-full h-full relative"> <div className="flex-1 flex overflow-hidden w-full h-full relative">
{/* Left Sidebar: hidden on mobile, rendered on tablet & desktop */} {/* Left Sidebar: hidden on mobile, rendered on tablet & desktop */}
{!isEffectiveMobile && <Sidebar isTabletCompact={isEffectiveTablet} />} {!isEffectiveMobile && (
<Sidebar
isTabletCompact={isEffectiveTablet || (!isEmulatedOnDesktop && width < 1366)}
/>
)}
{/* Center Work Area */} {/* Center Work Area */}
<div className="flex-1 flex flex-col min-w-0 overflow-hidden bg-krona-workspace"> <div className="flex-1 flex flex-col min-w-0 overflow-hidden bg-krona-workspace">

View file

@ -180,7 +180,7 @@ export const Topbar: React.FC = () => {
{/* Location Switcher */} {/* Location Switcher */}
{profile.locations.length > 1 && ( {profile.locations.length > 1 && (
<div className="relative group hidden lg:block"> <div className="relative group hidden 2xl:block">
<div className="flex items-center gap-1.5 bg-krona-surface border border-krona-border rounded-xl px-2.5 py-1.5 cursor-pointer hover:border-krona-gold/60 transition-colors shadow-xs"> <div className="flex items-center gap-1.5 bg-krona-surface border border-krona-border rounded-xl px-2.5 py-1.5 cursor-pointer hover:border-krona-gold/60 transition-colors shadow-xs">
<MapPin className="w-3.5 h-3.5 text-emerald-500 shrink-0" /> <MapPin className="w-3.5 h-3.5 text-emerald-500 shrink-0" />
<span className="text-xs font-medium text-krona-primary max-w-[130px] truncate"> <span className="text-xs font-medium text-krona-primary max-w-[130px] truncate">
@ -208,7 +208,7 @@ export const Topbar: React.FC = () => {
)} )}
{/* Role Badge (RBAC) */} {/* Role Badge (RBAC) */}
<div className="relative group hidden sm:block"> <div className="relative group hidden 2xl:block">
<button <button
type="button" type="button"
data-testid="role-switcher-btn" data-testid="role-switcher-btn"
@ -265,7 +265,7 @@ export const Topbar: React.FC = () => {
</div> </div>
{/* Center: Command Search Palette Trigger */} {/* Center: Command Search Palette Trigger */}
<div className="flex-1 max-w-sm mx-2"> <div className="flex-1 min-w-[220px] max-w-xl mx-2">
<button <button
onClick={() => setIsCommandPaletteOpen(true)} onClick={() => setIsCommandPaletteOpen(true)}
className="w-full flex items-center justify-between px-3 py-1.5 bg-krona-workspace border border-krona-border rounded-xl text-xs text-krona-secondary hover:text-krona-primary hover:border-krona-gold/60 transition-colors shadow-inner" className="w-full flex items-center justify-between px-3 py-1.5 bg-krona-workspace border border-krona-border rounded-xl text-xs text-krona-secondary hover:text-krona-primary hover:border-krona-gold/60 transition-colors shadow-inner"
@ -292,7 +292,7 @@ export const Topbar: React.FC = () => {
title="Krona AI — Бизнес-оркестратор" title="Krona AI — Бизнес-оркестратор"
> >
<Sparkles className="w-3.5 h-3.5 mr-1" /> <Sparkles className="w-3.5 h-3.5 mr-1" />
<span className="hidden xl:inline">Krona AI</span> <span className="hidden 2xl:inline">Krona AI</span>
</Button> </Button>
{/* Theme switcher (3 buttons) */} {/* Theme switcher (3 buttons) */}
@ -352,14 +352,6 @@ export const Topbar: React.FC = () => {
</div> </div>
</div> </div>
{/* Communications owns its local tabs inside the module. Keep only the
module title here so the shell does not render a duplicate menu. */}
{isCommunicationsModule && (
<div className="hidden md:flex h-10 px-5 border-t border-krona-border/60 bg-krona-workspace/40 items-center shrink-0">
<span className="font-serif text-lg font-bold text-krona-primary">Коммуникации</span>
</div>
)}
{/* Subheader / Subtabs Navigation Bar (Desktop & Tablet) */} {/* Subheader / Subtabs Navigation Bar (Desktop & Tablet) */}
{!isCommunicationsModule && activeSubtabs.length > 0 && ( {!isCommunicationsModule && activeSubtabs.length > 0 && (
<div className="h-10 px-4 border-t border-krona-border/60 bg-krona-workspace/40 flex items-center overflow-x-auto gap-1 text-xs"> <div className="h-10 px-4 border-t border-krona-border/60 bg-krona-workspace/40 flex items-center overflow-x-auto gap-1 text-xs">

View file

@ -696,15 +696,18 @@ export function MessengersView({ onOpenConnectModal, onOpenAddContactModal }: Me
</div> </div>
<div className="flex items-center gap-2 shrink-0"> <div className="flex items-center gap-2 shrink-0">
{onOpenConnectModal && <Button {onOpenConnectModal && (
variant="secondary" <div className="hidden sm:block">
size="sm" <Button
onClick={onOpenConnectModal} variant="secondary"
leftIcon={<Plus className="w-3.5 h-3.5 text-[var(--krona-primary)]" />} size="sm"
className="hidden sm:inline-flex" onClick={onOpenConnectModal}
> leftIcon={<Plus className="w-3.5 h-3.5 text-[var(--krona-primary)]" />}
Добавить мессенджер >
</Button>} Добавить мессенджер
</Button>
</div>
)}
{onOpenConnectModal && <button {onOpenConnectModal && <button
type="button" type="button"
onClick={onOpenConnectModal} onClick={onOpenConnectModal}

View file

@ -287,6 +287,27 @@ body {
overflow-x: hidden; overflow-x: hidden;
} }
/* The application shell and the shared component library use one semantic
surface. Keeping transitions here prevents each module from inventing its
own theme animation. */
body,
#root,
[data-testid="app-shell-root"] {
transition:
background-color var(--omni-motion-theme),
color var(--omni-motion-theme);
}
::selection {
background: var(--krona-primary-soft);
color: var(--krona-text-primary);
}
:focus-visible {
outline: 2px solid var(--krona-border-focus);
outline-offset: 2px;
}
/* Custom scrollbars according to design system */ /* Custom scrollbars according to design system */
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 6px; width: 6px;