@usecross/docs 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,317 @@
1
+ import { useState } from 'react'
2
+ import type { GriffeFunction, GriffeParameter, GriffeExpression } from '../../types'
3
+
4
+ /**
5
+ * Render a type annotation expression to string
6
+ */
7
+ function renderExpression(expr: GriffeExpression | string | undefined): string {
8
+ if (!expr) return ''
9
+ if (typeof expr === 'string') return expr
10
+ if (expr.str) return expr.str
11
+ if (expr.canonical) return expr.canonical
12
+
13
+ const exprAny = expr as any
14
+
15
+ // Handle ExprName with member reference
16
+ if (expr.name && typeof expr.name === 'string') return expr.name
17
+
18
+ // Handle ExprBoolOp (like `config or StrawberryConfig()`)
19
+ if (exprAny.cls === 'ExprBoolOp' && exprAny.operator && Array.isArray(exprAny.values)) {
20
+ return exprAny.values.map((v: any) => renderExpression(v)).join(` ${exprAny.operator} `)
21
+ }
22
+
23
+ // Handle ExprBinOp (like `type | None`)
24
+ if (exprAny.cls === 'ExprBinOp' && exprAny.left && exprAny.right) {
25
+ const left = renderExpression(exprAny.left)
26
+ const right = renderExpression(exprAny.right)
27
+ const op = exprAny.operator || '|'
28
+ return `${left} ${op} ${right}`
29
+ }
30
+
31
+ // Handle ExprCall (like `StrawberryConfig()`)
32
+ if (exprAny.cls === 'ExprCall' && exprAny.function) {
33
+ const funcName = renderExpression(exprAny.function)
34
+ const args = Array.isArray(exprAny.arguments)
35
+ ? exprAny.arguments.map((a: any) => renderExpression(a)).join(', ')
36
+ : ''
37
+ return `${funcName}(${args})`
38
+ }
39
+
40
+ // Handle ExprAttribute (like contextlib.asynccontextmanager)
41
+ if (exprAny.cls === 'ExprAttribute' && Array.isArray(exprAny.values)) {
42
+ return exprAny.values.map((v: any) => renderExpression(v)).join('.')
43
+ }
44
+
45
+ // Handle ExprList and ExprTuple
46
+ if ('elements' in exprAny && Array.isArray(exprAny.elements)) {
47
+ const inner = exprAny.elements.map((el: any) => renderExpression(el)).join(', ')
48
+ return exprAny.cls === 'ExprTuple' ? `(${inner})` : `[${inner}]`
49
+ }
50
+
51
+ // Handle ExprDict
52
+ if (exprAny.cls === 'ExprDict' && Array.isArray(exprAny.keys) && Array.isArray(exprAny.values)) {
53
+ const pairs = exprAny.keys.map((k: any, i: number) =>
54
+ `${renderExpression(k)}: ${renderExpression(exprAny.values[i])}`
55
+ ).join(', ')
56
+ return `{${pairs}}`
57
+ }
58
+
59
+ // Handle ExprSubscript (like Dict[str, int])
60
+ if (exprAny.left && exprAny.slice) {
61
+ const left = renderExpression(exprAny.left)
62
+ const slice = renderExpression(exprAny.slice)
63
+ return `${left}[${slice}]`
64
+ }
65
+
66
+ // Handle slice expressions
67
+ if ('slice' in exprAny && exprAny.slice && !exprAny.left) {
68
+ return renderExpression(exprAny.slice)
69
+ }
70
+
71
+ // Fallback for unknown expressions
72
+ if (typeof expr === 'object') {
73
+ return JSON.stringify(expr)
74
+ }
75
+
76
+ return String(expr)
77
+ }
78
+
79
+ /**
80
+ * Render a parameter with its type annotation and default value
81
+ */
82
+ function renderParameter(param: GriffeParameter): string {
83
+ let result = ''
84
+
85
+ // Handle special parameter kinds
86
+ if (param.kind === 'var-positional') {
87
+ result = `*${param.name}`
88
+ } else if (param.kind === 'var-keyword') {
89
+ result = `**${param.name}`
90
+ } else {
91
+ result = param.name
92
+ }
93
+
94
+ // Add type annotation
95
+ if (param.annotation) {
96
+ const annotation = renderExpression(param.annotation)
97
+ if (annotation) {
98
+ result += `: ${annotation}`
99
+ }
100
+ }
101
+
102
+ // Add default value
103
+ if (param.default) {
104
+ result += ` = ${renderExpression(param.default)}`
105
+ }
106
+
107
+ return result
108
+ }
109
+
110
+ /**
111
+ * Copy icon component
112
+ */
113
+ function CopyIcon() {
114
+ return (
115
+ <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
116
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
117
+ </svg>
118
+ )
119
+ }
120
+
121
+ /**
122
+ * Check icon component
123
+ */
124
+ function CheckIcon() {
125
+ return (
126
+ <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
127
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
128
+ </svg>
129
+ )
130
+ }
131
+
132
+ interface SignatureProps {
133
+ fn: GriffeFunction
134
+ /** Show full path or just function name */
135
+ showPath?: boolean
136
+ /** Additional CSS class */
137
+ className?: string
138
+ }
139
+
140
+ /**
141
+ * Renders a Python function/method signature with syntax highlighting.
142
+ * Uses dark background style matching strawberry.rocks.
143
+ */
144
+ export function Signature({ fn, showPath = false, className = '' }: SignatureProps) {
145
+ const [copied, setCopied] = useState(false)
146
+ const name = showPath && fn.path ? fn.path : fn.name
147
+ const isAsync = fn.is_async
148
+
149
+ // Filter out 'self' for cleaner display
150
+ const displayParams = fn.parameters?.filter(p => p.name !== 'self') ?? []
151
+
152
+ // Render return type
153
+ const returnType = renderExpression(fn.returns)
154
+
155
+ // Build parameter string with proper separators for positional-only and keyword-only
156
+ const buildParamString = (params: GriffeParameter[]): string => {
157
+ const parts: string[] = []
158
+ const hasVarPositional = params.some(p => p.kind === 'var-positional')
159
+ let addedBareAsterisk = false
160
+
161
+ for (let i = 0; i < params.length; i++) {
162
+ const param = params[i]
163
+ const nextParam = params[i + 1]
164
+
165
+ // Add the parameter itself
166
+ parts.push(renderParameter(param))
167
+
168
+ // Add / after last positional-only parameter
169
+ if (param.kind === 'positional-only' && nextParam && nextParam.kind !== 'positional-only') {
170
+ parts.push('/')
171
+ }
172
+
173
+ // Add bare * before first keyword-only parameter (if no *args)
174
+ if (!hasVarPositional && !addedBareAsterisk && nextParam?.kind === 'keyword-only' && param.kind !== 'keyword-only') {
175
+ parts.push('*')
176
+ addedBareAsterisk = true
177
+ }
178
+ }
179
+
180
+ return parts.join(', ')
181
+ }
182
+
183
+ // Build the plain text signature for copying
184
+ const plainSignature = (() => {
185
+ const params = buildParamString(displayParams)
186
+ const prefix = isAsync ? 'async def ' : 'def '
187
+ return returnType
188
+ ? `${prefix}${name}(${params}) -> ${returnType}`
189
+ : `${prefix}${name}(${params})`
190
+ })()
191
+
192
+ const handleCopy = async () => {
193
+ await navigator.clipboard.writeText(plainSignature)
194
+ setCopied(true)
195
+ setTimeout(() => setCopied(false), 2000)
196
+ }
197
+
198
+ // Build list of parameter tokens (params + separators like / and *)
199
+ type ParamToken = { type: 'param'; param: GriffeParameter } | { type: 'separator'; value: '/' | '*' }
200
+ const buildParamTokens = (params: GriffeParameter[]): ParamToken[] => {
201
+ const tokens: ParamToken[] = []
202
+ const hasVarPositional = params.some(p => p.kind === 'var-positional')
203
+ let addedBareAsterisk = false
204
+
205
+ for (let i = 0; i < params.length; i++) {
206
+ const param = params[i]
207
+ const nextParam = params[i + 1]
208
+
209
+ tokens.push({ type: 'param', param })
210
+
211
+ // Add / after last positional-only parameter
212
+ if (param.kind === 'positional-only' && nextParam && nextParam.kind !== 'positional-only') {
213
+ tokens.push({ type: 'separator', value: '/' })
214
+ }
215
+
216
+ // Add bare * before first keyword-only parameter (if no *args)
217
+ if (!hasVarPositional && !addedBareAsterisk && nextParam?.kind === 'keyword-only' && param.kind !== 'keyword-only') {
218
+ tokens.push({ type: 'separator', value: '*' })
219
+ addedBareAsterisk = true
220
+ }
221
+ }
222
+
223
+ return tokens
224
+ }
225
+
226
+ const paramTokens = buildParamTokens(displayParams)
227
+
228
+ // Render a single parameter element
229
+ const renderParamElement = (param: GriffeParameter, multiline: boolean) => (
230
+ <>
231
+ {param.kind === 'var-positional' && <span className="text-gray-400">*</span>}
232
+ {param.kind === 'var-keyword' && <span className="text-gray-400">**</span>}
233
+ <span className="text-orange-300">{param.name}</span>
234
+ {param.annotation && (
235
+ <>
236
+ <span className="text-gray-400">: </span>
237
+ <span className="text-emerald-400">{renderExpression(param.annotation)}</span>
238
+ </>
239
+ )}
240
+ {param.default && (
241
+ <>
242
+ <span className="text-gray-400"> = </span>
243
+ <span className="text-blue-300">{renderExpression(param.default)}</span>
244
+ </>
245
+ )}
246
+ {multiline && <span className="text-gray-400">,</span>}
247
+ </>
248
+ )
249
+
250
+ // Determine if we need multi-line formatting
251
+ const needsMultiline = displayParams.length > 3
252
+
253
+ return (
254
+ <div className={`relative group ${className}`}>
255
+ {/* Dark code block like strawberry.rocks */}
256
+ <div className="font-mono text-sm bg-gray-900 dark:bg-gray-950 rounded-lg p-4 overflow-x-auto">
257
+ <code className="text-gray-100">
258
+ {isAsync && <span className="text-purple-400">async </span>}
259
+ <span className="text-blue-400">def</span>
260
+ {' '}
261
+ <span className="text-yellow-300">{name}</span>
262
+ <span className="text-gray-400">(</span>
263
+ {paramTokens.length > 0 && (
264
+ needsMultiline ? (
265
+ // Multi-line for many parameters
266
+ <>
267
+ {paramTokens.map((token, i) => (
268
+ token.type === 'param' ? (
269
+ <span key={token.param.name} className="block pl-4">
270
+ {renderParamElement(token.param, true)}
271
+ </span>
272
+ ) : (
273
+ <span key={`sep-${i}`} className="block pl-4">
274
+ <span className="text-gray-400">{token.value},</span>
275
+ </span>
276
+ )
277
+ ))}
278
+ </>
279
+ ) : (
280
+ // Single line for few parameters
281
+ paramTokens.map((token, i) => (
282
+ token.type === 'param' ? (
283
+ <span key={token.param.name}>
284
+ {i > 0 && <span className="text-gray-400">, </span>}
285
+ {renderParamElement(token.param, false)}
286
+ </span>
287
+ ) : (
288
+ <span key={`sep-${i}`}>
289
+ <span className="text-gray-400">, {token.value}</span>
290
+ </span>
291
+ )
292
+ ))
293
+ )
294
+ )}
295
+ <span className="text-gray-400">)</span>
296
+ {returnType && (
297
+ <>
298
+ <span className="text-gray-400"> -&gt; </span>
299
+ <span className="text-emerald-400">{returnType}</span>
300
+ </>
301
+ )}
302
+ <span className="text-gray-400">:</span>
303
+ <span className="block pl-2 text-gray-500">...</span>
304
+ </code>
305
+ </div>
306
+
307
+ {/* Copy button */}
308
+ <button
309
+ onClick={handleCopy}
310
+ className="absolute top-3 right-3 p-1.5 rounded bg-gray-700 hover:bg-gray-600 opacity-0 group-hover:opacity-100 transition-opacity text-gray-300 hover:text-white"
311
+ title="Copy to clipboard"
312
+ >
313
+ {copied ? <CheckIcon /> : <CopyIcon />}
314
+ </button>
315
+ </div>
316
+ )
317
+ }
@@ -0,0 +1,50 @@
1
+ // Re-export the shared TableOfContents component
2
+ export { TableOfContents } from '../TableOfContents'
3
+ export type { TOCItem as TocItem } from '../../types'
4
+
5
+ /**
6
+ * Generate TOC items from a class's members
7
+ * Filters out private members (except __init__) to match ClassDoc rendering
8
+ */
9
+ export function generateClassToc(cls: {
10
+ name: string
11
+ members?: Record<string, { kind: string; name: string }>
12
+ }): { id: string; title: string; level: number }[] {
13
+ const items: { id: string; title: string; level: number }[] = []
14
+
15
+ // Add class name as top item
16
+ items.push({ id: cls.name, title: cls.name, level: 1 })
17
+
18
+ if (!cls.members) return items
19
+
20
+ const members = Object.values(cls.members)
21
+
22
+ // Filter methods: __init__ is special, skip other private/dunder methods
23
+ const methods = members.filter(m => m.kind === 'function')
24
+ const initMethod = methods.find(m => m.name === '__init__')
25
+ const publicMethods = methods
26
+ .filter(m => m.name !== '__init__' && !m.name.startsWith('_'))
27
+ .sort((a, b) => a.name.localeCompare(b.name))
28
+
29
+ // Filter attributes: skip private ones
30
+ const publicAttributes = members
31
+ .filter(m => m.kind === 'attribute' && !m.name.startsWith('_'))
32
+ .sort((a, b) => a.name.localeCompare(b.name))
33
+
34
+ // Add constructor section if exists
35
+ if (initMethod) {
36
+ items.push({ id: 'constructor', title: 'Constructor', level: 2 })
37
+ }
38
+
39
+ // Add methods section header if there are public methods
40
+ if (publicMethods.length > 0) {
41
+ items.push({ id: 'methods', title: 'Methods', level: 2 })
42
+ }
43
+
44
+ // Add attributes section header if there are public attributes
45
+ if (publicAttributes.length > 0) {
46
+ items.push({ id: 'attributes', title: 'Attributes', level: 2 })
47
+ }
48
+
49
+ return items
50
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * API Documentation Components
3
+ *
4
+ * Components for rendering Python API documentation generated by Griffe.
5
+ */
6
+
7
+ export { APIPage } from './APIPage'
8
+ export { APILayout } from './APILayout'
9
+ export { ModuleDoc } from './ModuleDoc'
10
+ export { ClassDoc } from './ClassDoc'
11
+ export { FunctionDoc } from './FunctionDoc'
12
+ export { Signature } from './Signature'
13
+ export { Docstring } from './Docstring'
14
+ export { ParameterTable } from './ParameterTable'
15
+ export { CodeSpan } from './CodeSpan'
16
+ export { TableOfContents, generateClassToc, type TocItem } from './TableOfContents'
17
+ export { Breadcrumb, generateBreadcrumb } from './Breadcrumb'
@@ -9,3 +9,15 @@ export { Sidebar } from './Sidebar'
9
9
  export { TableOfContents } from './TableOfContents'
10
10
  export { ThemeProvider, useTheme, themeInitScript } from './ThemeProvider'
11
11
  export { ThemeToggle } from './ThemeToggle'
12
+
13
+ // API Documentation Components
14
+ export {
15
+ APIPage,
16
+ APILayout,
17
+ ModuleDoc,
18
+ ClassDoc,
19
+ FunctionDoc,
20
+ Signature,
21
+ Docstring,
22
+ ParameterTable,
23
+ } from './api'
package/src/index.ts CHANGED
@@ -15,6 +15,15 @@ export {
15
15
  ThemeToggle,
16
16
  useTheme,
17
17
  themeInitScript,
18
+ // API Documentation Components
19
+ APIPage,
20
+ APILayout,
21
+ ModuleDoc,
22
+ ClassDoc,
23
+ FunctionDoc,
24
+ Signature,
25
+ Docstring,
26
+ ParameterTable,
18
27
  } from './components'
19
28
 
20
29
  // HomePage sub-components (for compound component pattern)
@@ -48,6 +57,28 @@ export type {
48
57
  SidebarProps,
49
58
  TableOfContentsProps,
50
59
  TOCItem,
60
+ // API Documentation Types
61
+ GriffeKind,
62
+ GriffeDocstringSectionKind,
63
+ GriffeExpression,
64
+ GriffeParameter,
65
+ GriffeDocstringElement,
66
+ GriffeDocstringSection,
67
+ GriffeDocstring,
68
+ GriffeDecorator,
69
+ GriffeObjectBase,
70
+ GriffeFunction,
71
+ GriffeAttribute,
72
+ GriffeClass,
73
+ GriffeModule,
74
+ GriffeMember,
75
+ APIPageProps,
76
+ ModuleDocProps,
77
+ ClassDocProps,
78
+ FunctionDocProps,
79
+ SignatureProps,
80
+ DocstringProps,
81
+ ParameterTableProps,
51
82
  } from './types'
52
83
 
53
84
  export type { Theme, ResolvedTheme } from './components/ThemeProvider'
package/src/types.ts CHANGED
@@ -53,7 +53,10 @@ export interface SharedProps {
53
53
  /** Table of contents item */
54
54
  export interface TOCItem {
55
55
  id: string
56
- text: string
56
+ /** Display text (use either text or title) */
57
+ text?: string
58
+ /** Display title (use either text or title) */
59
+ title?: string
57
60
  level: number
58
61
  }
59
62
 
@@ -96,7 +99,7 @@ export interface DocsLayoutProps {
96
99
  export interface TableOfContentsProps {
97
100
  items: TOCItem[]
98
101
  className?: string
99
- style: any
102
+ style?: React.CSSProperties
100
103
  }
101
104
 
102
105
  /** Props for Sidebar component */
@@ -134,3 +137,216 @@ export interface DocsAppConfig {
134
137
  /** Custom components to use in markdown (e.g., Alert, Card, etc.) */
135
138
  components?: Record<string, React.ComponentType<any>>
136
139
  }
140
+
141
+ // =============================================================================
142
+ // Griffe API Documentation Types
143
+ // =============================================================================
144
+
145
+ /** Griffe object kinds */
146
+ export type GriffeKind = 'module' | 'class' | 'function' | 'attribute'
147
+
148
+ /** Griffe docstring section kinds */
149
+ export type GriffeDocstringSectionKind =
150
+ | 'text'
151
+ | 'parameters'
152
+ | 'returns'
153
+ | 'yields'
154
+ | 'receives'
155
+ | 'raises'
156
+ | 'warns'
157
+ | 'examples'
158
+ | 'attributes'
159
+ | 'other'
160
+ | 'deprecated'
161
+ | 'admonition'
162
+
163
+ /** Griffe expression (type annotation) */
164
+ export interface GriffeExpression {
165
+ /** String representation of the expression */
166
+ str?: string
167
+ /** Canonical string representation */
168
+ canonical?: string
169
+ /** For name expressions */
170
+ name?: string
171
+ /** For subscript expressions (e.g., List[int]) */
172
+ slice?: GriffeExpression
173
+ /** For compound expressions */
174
+ left?: GriffeExpression
175
+ right?: GriffeExpression
176
+ }
177
+
178
+ /** Griffe parameter */
179
+ export interface GriffeParameter {
180
+ name: string
181
+ kind: 'positional-only' | 'positional-or-keyword' | 'var-positional' | 'keyword-only' | 'var-keyword'
182
+ annotation?: GriffeExpression | string
183
+ default?: string
184
+ }
185
+
186
+ /** Griffe docstring section element (for parameters, returns, etc.) */
187
+ export interface GriffeDocstringElement {
188
+ name?: string
189
+ annotation?: GriffeExpression | string
190
+ description?: string
191
+ value?: string
192
+ }
193
+
194
+ /** Griffe docstring section */
195
+ export interface GriffeDocstringSection {
196
+ kind: GriffeDocstringSectionKind
197
+ value?: string | GriffeDocstringElement[]
198
+ title?: string
199
+ }
200
+
201
+ /** Griffe parsed docstring */
202
+ export interface GriffeDocstring {
203
+ value: string
204
+ parsed?: GriffeDocstringSection[]
205
+ }
206
+
207
+ /** Griffe decorator */
208
+ export interface GriffeDecorator {
209
+ value: string
210
+ lineno?: number
211
+ }
212
+
213
+ /** Base Griffe object with common properties */
214
+ export interface GriffeObjectBase {
215
+ kind: GriffeKind
216
+ name: string
217
+ path?: string
218
+ filepath?: string
219
+ /** Relative file path (set by cross-docs) */
220
+ relative_filepath?: string
221
+ /** Relative file path within the package (set by Griffe) */
222
+ relative_package_filepath?: string
223
+ lineno?: number
224
+ endlineno?: number
225
+ docstring?: GriffeDocstring
226
+ labels?: string[]
227
+ }
228
+
229
+ /** Griffe function/method */
230
+ export interface GriffeFunction extends GriffeObjectBase {
231
+ kind: 'function'
232
+ parameters?: GriffeParameter[]
233
+ returns?: GriffeExpression | string
234
+ decorators?: GriffeDecorator[]
235
+ /** Whether this is an async function */
236
+ is_async?: boolean
237
+ }
238
+
239
+ /** Griffe attribute */
240
+ export interface GriffeAttribute extends GriffeObjectBase {
241
+ kind: 'attribute'
242
+ annotation?: GriffeExpression | string
243
+ value?: string
244
+ }
245
+
246
+ /** Griffe class */
247
+ export interface GriffeClass extends GriffeObjectBase {
248
+ kind: 'class'
249
+ bases?: Array<GriffeExpression | string>
250
+ decorators?: GriffeDecorator[]
251
+ members?: Record<string, GriffeMember>
252
+ }
253
+
254
+ /** Griffe module */
255
+ export interface GriffeModule extends GriffeObjectBase {
256
+ kind: 'module'
257
+ members?: Record<string, GriffeMember>
258
+ /** Generator metadata added by cross-docs */
259
+ _generator?: string
260
+ _plugin?: string
261
+ _version?: string
262
+ }
263
+
264
+ /** Griffe alias (re-export) */
265
+ export interface GriffeAlias {
266
+ kind: 'alias'
267
+ name: string
268
+ path?: string
269
+ /** The target path this alias points to */
270
+ target_path: string
271
+ lineno?: number
272
+ endlineno?: number
273
+ }
274
+
275
+ /** Union of all Griffe member types */
276
+ export type GriffeMember = GriffeModule | GriffeClass | GriffeFunction | GriffeAttribute | GriffeAlias
277
+
278
+ /** Props for API documentation pages */
279
+ export interface APIPageProps {
280
+ /** Full API data (the entire module tree) */
281
+ apiData: GriffeModule
282
+ /** Current item being viewed (module, class, or function) */
283
+ currentItem?: GriffeMember
284
+ /** Current URL path */
285
+ currentPath: string
286
+ /** Current module name */
287
+ currentModule: string
288
+ /** Navigation structure for API sidebar */
289
+ apiNav: NavSection[]
290
+ /** URL prefix for API links (e.g., /docs/api-reference) */
291
+ prefix: string
292
+ /** Logo URL */
293
+ logoUrl?: string
294
+ /** Logo URL for dark mode */
295
+ logoInvertedUrl?: string
296
+ /** Footer logo URL */
297
+ footerLogoUrl?: string
298
+ /** Footer logo URL for dark mode */
299
+ footerLogoInvertedUrl?: string
300
+ /** GitHub URL */
301
+ githubUrl?: string
302
+ /** Navigation links */
303
+ navLinks?: Array<{ label: string; href: string }>
304
+ /** Custom header component (replaces entire header). Can be a ReactNode or a function that receives mobile menu props. */
305
+ header?: React.ReactNode | ((props: { mobileMenuOpen: boolean; toggleMobileMenu: () => void }) => React.ReactNode)
306
+ /** Header height in pixels. Used to calculate content offset. Defaults to 64 (h-16). */
307
+ headerHeight?: number
308
+ /** Custom footer component */
309
+ footer?: React.ReactNode
310
+ }
311
+
312
+ /** Props for ModuleDoc component */
313
+ export interface ModuleDocProps {
314
+ module: GriffeModule
315
+ /** URL prefix for links */
316
+ prefix?: string
317
+ }
318
+
319
+ /** Props for ClassDoc component */
320
+ export interface ClassDocProps {
321
+ cls: GriffeClass
322
+ /** URL prefix for links */
323
+ prefix?: string
324
+ }
325
+
326
+ /** Props for FunctionDoc component */
327
+ export interface FunctionDocProps {
328
+ fn: GriffeFunction
329
+ /** Whether this is a method (inside a class) */
330
+ isMethod?: boolean
331
+ }
332
+
333
+ /** Props for Signature component */
334
+ export interface SignatureProps {
335
+ fn: GriffeFunction
336
+ /** Show full path or just name */
337
+ showPath?: boolean
338
+ }
339
+
340
+ /** Props for Docstring component */
341
+ export interface DocstringProps {
342
+ docstring: GriffeDocstring
343
+ /** Show raw text instead of parsed sections */
344
+ raw?: boolean
345
+ }
346
+
347
+ /** Props for ParameterTable component */
348
+ export interface ParameterTableProps {
349
+ parameters: GriffeParameter[]
350
+ /** Docstring sections for parameter descriptions */
351
+ docstringSections?: GriffeDocstringSection[]
352
+ }