feat: workspace tabs as side-by-side segmented control in sidebar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-05-19 20:40:12 +02:00
parent 315733a423
commit 86051c6f01
+23 -21
View File
@@ -147,7 +147,6 @@ const SIDEBAR_BG = '#0f1923'
const DIVIDER_COLOR = 'rgba(255,255,255,0.08)'
const TEXT_MUTED = '#94a3b8'
const TEXT_WHITE = '#ffffff'
const ACTIVE_BG = 'rgba(255,255,255,0.1)'
const NAV_ACTIVE_BG = 'rgba(255,255,255,0.12)'
const NAV_HOVER_BG = 'rgba(255,255,255,0.06)'
@@ -173,7 +172,7 @@ function Sidebar({
orgName,
}: SidebarProps) {
const config = WORKSPACE_CONFIG[activeWorkspace]
const width = collapsed ? 60 : 240
const width = collapsed ? 60 : 264
const visibleWorkspaces = WORKSPACE_ORDER.filter((ws) => allowedWorkspaces.includes(ws))
return (
@@ -234,16 +233,16 @@ function Sidebar({
)}
</Box>
{/* Workspace tabs */}
{/* Workspace tabs — side-by-side segmented control */}
<Box
sx={{
borderBottom: `1px solid ${DIVIDER_COLOR}`,
py: 0.5,
px: 0.5,
display: 'grid',
gridTemplateColumns: collapsed ? '1fr' : `repeat(${visibleWorkspaces.length}, 1fr)`,
flexShrink: 0,
}}
>
{visibleWorkspaces.map((ws) => {
{visibleWorkspaces.map((ws, idx) => {
const wsConfig = WORKSPACE_CONFIG[ws]
const Icon = wsConfig.icon
const isActive = ws === activeWorkspace
@@ -253,29 +252,32 @@ function Sidebar({
onClick={() => { onWorkspaceClick(ws); onClose?.() }}
sx={{
display: 'flex',
flexDirection: collapsed ? 'row' : 'column',
alignItems: 'center',
gap: 1.25,
px: collapsed ? 0 : 1.5,
py: 0.75,
borderRadius: 1,
justifyContent: 'center',
gap: collapsed ? 0 : 0.5,
py: collapsed ? 1 : 1.25,
cursor: 'pointer',
justifyContent: collapsed ? 'center' : 'flex-start',
backgroundColor: isActive ? ACTIVE_BG : 'transparent',
'&:hover': {
backgroundColor: isActive ? ACTIVE_BG : NAV_HOVER_BG,
},
backgroundColor: isActive ? wsConfig.chipColor : 'transparent',
borderRight: !collapsed && idx < visibleWorkspaces.length - 1
? `1px solid ${DIVIDER_COLOR}`
: 'none',
transition: 'background-color 0.15s ease',
'&:hover': {
backgroundColor: isActive ? wsConfig.chipColor : NAV_HOVER_BG,
},
}}
>
<Icon size={16} color={isActive ? TEXT_WHITE : TEXT_MUTED} />
<Icon size={15} color={isActive ? TEXT_WHITE : TEXT_MUTED} />
{!collapsed && (
<Typography
variant="body2"
variant="caption"
sx={{
color: isActive ? TEXT_WHITE : TEXT_MUTED,
fontWeight: isActive ? 600 : 400,
fontSize: '0.8125rem',
whiteSpace: 'nowrap',
fontWeight: isActive ? 700 : 400,
fontSize: '0.6875rem',
lineHeight: 1,
letterSpacing: 0.2,
}}
>
{wsConfig.label}
@@ -557,7 +559,7 @@ export function AppShell() {
onClose={() => setMobileOpen(false)}
variant="temporary"
ModalProps={{ keepMounted: true }}
slotProps={{ paper: { sx: { width: 240, bgcolor: 'transparent', boxShadow: 'none' } } }}
slotProps={{ paper: { sx: { width: 264, bgcolor: 'transparent', boxShadow: 'none' } } }}
>
{sidebarContent}
</Drawer>