Files
MarkLite/src/renderer/components/OutlinePanel/OutlinePanel.tsx
T
thzxx 0940c2f5c6 fix: resolve all TS errors, ESLint warnings, and npm warnings bump to v0.3.12
- Pin all @milkdown/* packages to exact 7.21.1, add phantom-dep plugins as direct deps

- Fix TextSelection.create type error in useMilkdown.ts

- Fix Backspace auto-pair dead-code bug (unreachable due to PAIRS check order)

- Extract parseHeadings/Heading to outlineUtils.ts (react-refresh fix)

- Extract StatusBar item components to StatusBarItems.tsx (react-refresh fix)

- Configure npm allowScripts for electron and esbuild postinstall

- Update QUALITY_REVIEW_REPORT.json with all fixes applied

- Bump version to 0.3.12
2026-07-06 10:51:39 +08:00

72 lines
1.9 KiB
TypeScript

import React, { memo } from 'react'
import type { Heading } from './outlineUtils'
// --- Component ---
interface OutlinePanelProps {
headings: Heading[]
onNavigate: (heading: Heading, index: number) => void
activeHeadingIndex: number | null
}
interface OutlineItemProps {
heading: Heading
index: number
isActive: boolean
onNavigate: (heading: Heading, index: number) => void
}
const OutlineItem = memo(function OutlineItem({
heading,
index,
isActive,
onNavigate
}: OutlineItemProps) {
return (
<button
className={`outline-item outline-level-${heading.level}${isActive ? ' active' : ''}`}
onClick={() => onNavigate(heading, index)}
title={heading.text}
aria-label={`跳转到标题:${heading.text}`}
style={{ paddingLeft: `${8 + (heading.level - 1) * 12}px` }}
>
<span className="outline-level-dot" />
<span className="outline-item-text">{heading.text}</span>
</button>
)
})
export const OutlinePanel = memo(function OutlinePanel({
headings,
onNavigate,
activeHeadingIndex
}: OutlinePanelProps) {
if (headings.length === 0) {
return (
<div className="outline-panel" role="region" aria-label="文档大纲">
<div className="outline-header">文档大纲</div>
<div className="outline-empty">当前文档无标题</div>
</div>
)
}
return (
<div className="outline-panel" role="region" aria-label="文档大纲">
<div className="outline-header">文档大纲</div>
<div className="outline-list" role="list" aria-label="标题列表">
{headings.map((h, i) => (
<OutlineItem
key={`${h.text}-${i}`}
heading={h}
index={i}
isActive={i === activeHeadingIndex}
onNavigate={onNavigate}
/>
))}
</div>
</div>
)
})
OutlinePanel.displayName = 'OutlinePanel'