Skip to content

Commit 2b8b3cc

Browse files
committed
```
feat(app): 实现移动端侧边栏及增强页面导航功能 新增移动端适配的抽屉式侧边栏,支持键盘事件关闭与页面滚动锁定。 引入活动标签页标题显示、增强搜索高亮与键盘导航功能。 优化页面大纲组件,支持自动检测当前可视区域标题并高亮。 添加 OG 图片与 Canonical 链接,提升 SEO 与社交分享体验。 注册新页面组件:端到端走读、Innies 改造总览,并更新导航结构。 ```
1 parent 2f8701f commit 2b8b3cc

9 files changed

Lines changed: 541 additions & 51 deletions

File tree

index.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,23 @@
1717
<meta property="og:url" content="https://tt-a1i.github.io/coding-cli-guide/" />
1818
<meta property="og:site_name" content="Innies CLI Guide" />
1919
<meta property="og:locale" content="zh_CN" />
20+
<meta property="og:image" content="https://tt-a1i.github.io/coding-cli-guide/og.png" />
21+
<meta property="og:image:width" content="1200" />
22+
<meta property="og:image:height" content="630" />
2023

2124
<!-- Twitter Card -->
2225
<meta name="twitter:card" content="summary_large_image" />
2326
<meta name="twitter:title" content="Innies CLI 架构学习指南" />
2427
<meta name="twitter:description" content="深入理解 Innies CLI 的内部架构与 AI 工具交互模式" />
28+
<meta name="twitter:image" content="https://tt-a1i.github.io/coding-cli-guide/og.png" />
2529

2630
<!-- Favicon -->
2731
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
2832
<link rel="apple-touch-icon" href="/favicon.svg" />
2933

34+
<!-- Canonical -->
35+
<link rel="canonical" href="https://tt-a1i.github.io/coding-cli-guide/" />
36+
3037
<!-- Theme Color -->
3138
<meta name="theme-color" content="#0f172a" />
3239

public/og.png

356 KB
Loading

public/og.svg

Lines changed: 77 additions & 0 deletions
Loading

src/App.tsx

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { StartHere } from './pages/StartHere';
99
import { Overview } from './pages/Overview';
1010

1111
// 懒加载的页面
12+
const EndToEndWalkthrough = lazy(() => import('./pages/EndToEndWalkthrough').then(m => ({ default: m.EndToEndWalkthrough })));
13+
const UpstreamDiffOverview = lazy(() => import('./pages/UpstreamDiffOverview').then(m => ({ default: m.UpstreamDiffOverview })));
1214
const StartupFlow = lazy(() => import('./pages/StartupFlow').then(m => ({ default: m.StartupFlow })));
1315
const StartupChain = lazy(() => import('./pages/StartupChain').then(m => ({ default: m.StartupChain })));
1416
const ConfigSystem = lazy(() => import('./pages/ConfigSystem').then(m => ({ default: m.ConfigSystem })));
@@ -64,6 +66,7 @@ function PageLoading() {
6466
}
6567

6668
function App() {
69+
const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState(false);
6770
const validTabIds = useMemo(() => new Set(flatNavItems.map((i) => i.id)), []);
6871

6972
const getTabFromUrl = useCallback(() => {
@@ -92,6 +95,29 @@ function App() {
9295
[validTabIds]
9396
);
9497

98+
const activeTabLabel = useMemo(() => {
99+
const item = flatNavItems.find((i) => i.id === activeTab);
100+
return item?.label ?? 'Innies CLI';
101+
}, [activeTab]);
102+
103+
useEffect(() => {
104+
if (!isMobileSidebarOpen) return;
105+
const onKeyDown = (e: KeyboardEvent) => {
106+
if (e.key === 'Escape') setIsMobileSidebarOpen(false);
107+
};
108+
window.addEventListener('keydown', onKeyDown);
109+
return () => window.removeEventListener('keydown', onKeyDown);
110+
}, [isMobileSidebarOpen]);
111+
112+
useEffect(() => {
113+
if (!isMobileSidebarOpen) return;
114+
const prevOverflow = document.body.style.overflow;
115+
document.body.style.overflow = 'hidden';
116+
return () => {
117+
document.body.style.overflow = prevOverflow;
118+
};
119+
}, [isMobileSidebarOpen]);
120+
95121
useEffect(() => {
96122
const onPopState = () => {
97123
setActiveTab(getTabFromUrl());
@@ -112,6 +138,10 @@ function App() {
112138
switch (activeTab) {
113139
case 'start-here':
114140
return <StartHere onNavigate={(tab) => navigateToTab(tab)} />;
141+
case 'e2e':
142+
return <EndToEndWalkthrough />;
143+
case 'upstream-diff':
144+
return <UpstreamDiffOverview />;
115145
case 'overview':
116146
return <Overview />;
117147
case 'startup':
@@ -203,12 +233,60 @@ function App() {
203233

204234
return (
205235
<div className="flex min-h-screen bg-gray-950">
206-
{/* Sidebar */}
207-
<Sidebar activeTab={activeTab} onTabChange={(tab) => navigateToTab(tab)} />
236+
{/* Desktop Sidebar */}
237+
<div className="hidden md:block">
238+
<Sidebar activeTab={activeTab} onTabChange={(tab) => navigateToTab(tab)} />
239+
</div>
240+
241+
{/* Mobile Sidebar Drawer */}
242+
{isMobileSidebarOpen && (
243+
<div className="md:hidden fixed inset-0 z-50">
244+
<button
245+
aria-label="Close sidebar overlay"
246+
onClick={() => setIsMobileSidebarOpen(false)}
247+
className="absolute inset-0 bg-black/60"
248+
/>
249+
<div className="absolute inset-y-0 left-0 w-72 max-w-[85vw] shadow-2xl">
250+
<Sidebar
251+
activeTab={activeTab}
252+
onTabChange={(tab) => {
253+
navigateToTab(tab);
254+
setIsMobileSidebarOpen(false);
255+
}}
256+
/>
257+
</div>
258+
</div>
259+
)}
208260

209261
{/* Main Content */}
210262
<main className="flex-1 overflow-y-auto">
211-
<div className="max-w-5xl mx-auto p-8">
263+
{/* Mobile Top Bar */}
264+
<div className="md:hidden sticky top-0 z-20 bg-gray-950/80 backdrop-blur border-b border-gray-800">
265+
<div className="px-4 py-3 flex items-center gap-3">
266+
<button
267+
onClick={() => setIsMobileSidebarOpen(true)}
268+
className="px-3 py-2 rounded-lg bg-gray-900/30 border border-gray-800 text-gray-200 hover:bg-gray-800/40"
269+
aria-label="Open sidebar"
270+
>
271+
272+
</button>
273+
<div className="flex-1 min-w-0">
274+
<div className="text-sm text-gray-200 truncate">{activeTabLabel}</div>
275+
<div className="text-xs text-gray-500 truncate">
276+
搜索页面:Ctrl/⌘ + K
277+
</div>
278+
</div>
279+
<button
280+
onClick={() => navigateToTab('start-here')}
281+
className="px-3 py-2 rounded-lg bg-gray-900/30 border border-gray-800 text-gray-200 hover:bg-gray-800/40"
282+
aria-label="Go to start"
283+
>
284+
285+
</button>
286+
</div>
287+
</div>
288+
289+
<div className="max-w-5xl mx-auto p-4 md:p-8">
212290
<div className="animate-fadeIn">
213291
<PageLayout activeTab={activeTab} onNavigate={navigateToTab}>
214292
<Suspense fallback={<PageLoading />}>

0 commit comments

Comments
 (0)