296 lines
No EOL
10 KiB
TypeScript
296 lines
No EOL
10 KiB
TypeScript
import { cn } from '@/lib/utils'
|
|
import { colors, surfaces, effects } from '@/lib/theme'
|
|
import type { DocItem } from '@/lib/docs/types'
|
|
import CodeBlock from './CodeBlock'
|
|
import TypeLink from './TypeLink'
|
|
import { ExternalLink, TriangleAlert } from 'lucide-react'
|
|
import ReactMarkdown from 'react-markdown'
|
|
import remarkGfm from 'remark-gfm'
|
|
|
|
interface FunctionDocProps {
|
|
item: DocItem
|
|
className?: string
|
|
availableTypeIds?: Set<string>
|
|
}
|
|
|
|
export default function FunctionDoc({ item, className, availableTypeIds }: FunctionDocProps) {
|
|
return (
|
|
<div id={item.id} className={cn('scroll-mt-20', className)}>
|
|
<div className="space-y-6">
|
|
{/* Header */}
|
|
<div className="flex items-start justify-between gap-4">
|
|
<div className="space-y-3">
|
|
<div className="flex items-center gap-3 flex-wrap">
|
|
<h3 className="text-2xl font-bold" style={{ color: colors.text.primary }}>
|
|
{item.name}
|
|
</h3>
|
|
<span
|
|
className={cn(
|
|
'rounded-md px-2.5 py-1 text-xs font-medium'
|
|
)}
|
|
style={{
|
|
backgroundColor: colors.backgrounds.card,
|
|
color: colors.text.secondary
|
|
}}
|
|
>
|
|
{item.kind}
|
|
</span>
|
|
<span
|
|
className={cn(
|
|
'rounded-md px-2.5 py-1 text-xs font-medium'
|
|
)}
|
|
style={{
|
|
backgroundColor: colors.accents.docsBg,
|
|
color: colors.accents.docs,
|
|
borderWidth: '1px',
|
|
borderColor: colors.accents.docsBorder
|
|
}}
|
|
>
|
|
{item.category}
|
|
</span>
|
|
{item.deprecated && (
|
|
<span
|
|
className={cn(
|
|
'flex items-center gap-1.5 rounded-md px-2.5 py-1 text-xs font-medium'
|
|
)}
|
|
style={{
|
|
backgroundColor: colors.accents.warningBg,
|
|
color: colors.accents.warning
|
|
}}
|
|
>
|
|
<TriangleAlert className="h-3 w-3" />
|
|
Deprecated
|
|
</span>
|
|
)}
|
|
</div>
|
|
{item.description && (
|
|
<p className="leading-relaxed" style={{ color: colors.text.body }}>
|
|
{item.description}
|
|
</p>
|
|
)}
|
|
</div>
|
|
{item.source && (
|
|
<a
|
|
href={`https://github.com/ihatenodejs/aidxnCC/blob/main/${item.source.file}#L${item.source.line}`}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className={cn(
|
|
'flex items-center gap-1.5 rounded-md px-3 py-2',
|
|
'text-xs border-2',
|
|
effects.transitions.colors,
|
|
'flex-shrink-0'
|
|
)}
|
|
style={{
|
|
color: colors.text.muted,
|
|
borderColor: colors.borders.default
|
|
}}
|
|
onMouseEnter={(e) => {
|
|
e.currentTarget.style.borderColor = colors.borders.hover
|
|
e.currentTarget.style.color = colors.text.secondary
|
|
}}
|
|
onMouseLeave={(e) => {
|
|
e.currentTarget.style.borderColor = colors.borders.default
|
|
e.currentTarget.style.color = colors.text.muted
|
|
}}
|
|
>
|
|
<ExternalLink className="h-3.5 w-3.5" />
|
|
Source
|
|
</a>
|
|
)}
|
|
</div>
|
|
|
|
{/* Remarks */}
|
|
{item.remarks && (
|
|
<div
|
|
className={cn(
|
|
'rounded-lg border-l-4 pl-4 py-2',
|
|
'space-y-2'
|
|
)}
|
|
style={{
|
|
borderColor: colors.accents.ai,
|
|
backgroundColor: colors.backgrounds.card
|
|
}}
|
|
>
|
|
<h4 className="text-sm font-semibold" style={{ color: colors.text.secondary }}>
|
|
Remarks
|
|
</h4>
|
|
<div className="text-sm leading-relaxed prose prose-invert prose-sm max-w-none" style={{ color: colors.text.body }}>
|
|
<ReactMarkdown remarkPlugins={[remarkGfm]}>
|
|
{item.remarks}
|
|
</ReactMarkdown>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Signature */}
|
|
{item.signature && (
|
|
<div className="space-y-3">
|
|
<h4 className="text-sm font-semibold" style={{ color: colors.text.secondary }}>
|
|
Signature
|
|
</h4>
|
|
<CodeBlock code={item.signature} language="typescript" />
|
|
</div>
|
|
)}
|
|
|
|
{/* Parameters */}
|
|
{item.parameters && item.parameters.length > 0 && (
|
|
<div className="space-y-3">
|
|
<h4 className="text-sm font-semibold" style={{ color: colors.text.secondary }}>
|
|
Parameters
|
|
</h4>
|
|
<div className="overflow-x-auto rounded-lg border-2" style={{ borderColor: colors.borders.default }}>
|
|
<table className="w-full text-sm">
|
|
<thead>
|
|
<tr className="border-b-2" style={{ borderColor: colors.borders.default, backgroundColor: colors.backgrounds.card }}>
|
|
<th className="px-4 py-3 text-left font-medium" style={{ color: colors.text.muted }}>
|
|
Name
|
|
</th>
|
|
<th className="px-4 py-3 text-left font-medium" style={{ color: colors.text.muted }}>
|
|
Type
|
|
</th>
|
|
<th className="px-4 py-3 text-left font-medium" style={{ color: colors.text.muted }}>
|
|
Description
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{item.parameters.map((param, index) => (
|
|
<tr
|
|
key={index}
|
|
className="border-b last:border-0"
|
|
style={{ borderColor: colors.borders.subtle }}
|
|
>
|
|
<td className="px-4 py-3 font-mono" style={{ color: colors.text.secondary }}>
|
|
{param.name}
|
|
{param.optional && (
|
|
<span style={{ color: colors.text.disabled }}>?</span>
|
|
)}
|
|
</td>
|
|
<td className="px-4 py-3">
|
|
<TypeLink type={param.type} className="text-sm" availableTypeIds={availableTypeIds} />
|
|
</td>
|
|
<td className="px-4 py-3" style={{ color: colors.text.body }}>
|
|
{param.description || '—'}
|
|
{param.defaultValue && (
|
|
<div className="mt-1 text-xs" style={{ color: colors.text.disabled }}>
|
|
Default: <code>{param.defaultValue}</code>
|
|
</div>
|
|
)}
|
|
</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Returns */}
|
|
{item.returns && (
|
|
<div className="space-y-3">
|
|
<h4 className="text-sm font-semibold" style={{ color: colors.text.secondary }}>
|
|
Returns
|
|
</h4>
|
|
<div
|
|
className={cn(
|
|
'rounded-lg border-2 p-4',
|
|
'space-y-2'
|
|
)}
|
|
style={{
|
|
borderColor: colors.borders.default,
|
|
backgroundColor: colors.backgrounds.card
|
|
}}
|
|
>
|
|
<TypeLink type={item.returns.type} className="text-sm" availableTypeIds={availableTypeIds} />
|
|
{item.returns.description && (
|
|
<p className="text-sm" style={{ color: colors.text.body }}>
|
|
{item.returns.description}
|
|
</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Throws */}
|
|
{item.throws && item.throws.length > 0 && (
|
|
<div className="space-y-3">
|
|
<h4 className="text-sm font-semibold" style={{ color: colors.text.secondary }}>
|
|
Throws
|
|
</h4>
|
|
<div className="space-y-2">
|
|
{item.throws.map((throwsDoc, index) => (
|
|
<div
|
|
key={index}
|
|
className={cn(
|
|
'rounded-lg border-2 p-4'
|
|
)}
|
|
style={{
|
|
borderColor: colors.accents.warningBg,
|
|
backgroundColor: colors.backgrounds.card
|
|
}}
|
|
>
|
|
<p className="text-sm" style={{ color: colors.text.body }}>
|
|
{throwsDoc}
|
|
</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Examples */}
|
|
{item.examples && item.examples.length > 0 && (
|
|
<div className="space-y-3">
|
|
<h4 className="text-sm font-semibold" style={{ color: colors.text.secondary }}>
|
|
Examples
|
|
</h4>
|
|
<div className="space-y-4">
|
|
{item.examples.map((example, index) => (
|
|
<CodeBlock
|
|
key={index}
|
|
code={example.code}
|
|
language={example.language}
|
|
showLineNumbers
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Tags */}
|
|
{item.tags && item.tags.length > 0 && (
|
|
<div className="flex flex-wrap gap-2">
|
|
{item.tags.map((tag) => (
|
|
<span
|
|
key={tag}
|
|
className={cn(surfaces.badge.muted)}
|
|
>
|
|
{tag}
|
|
</span>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
{/* See Also */}
|
|
{item.see && item.see.length > 0 && (
|
|
<div className="space-y-3">
|
|
<h4 className="text-sm font-semibold" style={{ color: colors.text.secondary }}>
|
|
See Also
|
|
</h4>
|
|
<div className="space-y-2">
|
|
{item.see.map((ref, index) => (
|
|
<div
|
|
key={index}
|
|
className="text-sm"
|
|
style={{ color: colors.text.body }}
|
|
>
|
|
{ref}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)
|
|
} |