This commit is contained in:
Chris Wanstrath 2026-02-08 14:19:00 -08:00
parent b43c1b4660
commit 96289f7e30

View File

@ -0,0 +1,76 @@
import type { CSSProperties } from 'hono/jsx'
import {
apps,
selectedApp,
setSelectedApp,
setSidebarSection,
sidebarSection,
} from '../state'
import {
AppItem,
AppList,
SectionSwitcher,
SectionTab,
StatusDot,
} from '../styles'
interface AppSelectorProps {
render: () => void
onSelect?: () => void
collapsed?: boolean
switcherStyle?: CSSProperties
listStyle?: CSSProperties
}
export function AppSelector({ render, onSelect, collapsed, switcherStyle, listStyle }: AppSelectorProps) {
const selectApp = (name: string) => {
setSelectedApp(name)
onSelect?.()
render()
}
const switchSection = (section: 'apps' | 'tools') => {
setSidebarSection(section)
render()
}
const regularApps = apps.filter(app => !app.tool)
const toolApps = apps.filter(app => app.tool)
const activeApps = sidebarSection === 'apps' ? regularApps : toolApps
return (
<>
{!collapsed && toolApps.length > 0 && (
<SectionSwitcher style={switcherStyle}>
<SectionTab active={sidebarSection === 'apps' ? true : undefined} onClick={() => switchSection('apps')}>
Apps
</SectionTab>
<SectionTab active={sidebarSection === 'tools' ? true : undefined} onClick={() => switchSection('tools')}>
Tools
</SectionTab>
</SectionSwitcher>
)}
<AppList style={listStyle}>
{activeApps.map(app => (
<AppItem
key={app.name}
onClick={() => selectApp(app.name)}
selected={app.name === selectedApp ? true : undefined}
style={collapsed ? { justifyContent: 'center', padding: '10px 12px' } : undefined}
title={collapsed ? app.name : undefined}
>
{collapsed ? (
<span style={{ fontSize: 18 }}>{app.icon}</span>
) : (
<>
<span style={{ fontSize: 14 }}>{app.icon}</span>
{app.name}
<StatusDot state={app.state} style={{ marginLeft: 'auto' }} />
</>
)}
</AppItem>
))}
</AppList>
</>
)
}