This guide shows how to document components, functions, and types using TSDoc.
/**
* A reusable button component for the Bucketlist CMS
*
* @component
* @example
* ```tsx
* <Button onClick={handleClick} variant="primary">
* Save Changes
* </Button>
* ```
*/
export const Button: React.FC<ButtonProps> = ({ children, onClick, variant }) => {
// Implementation
}interface FieldRendererProps {
/** The schema field definition to render */
field: SchemaField
/** Current value of the field */
value: any
/** Callback fired when the field value changes */
onChange: (value: any) => void
/** S3 bucket name for image uploads */
bucket?: string
/** Set of field names currently uploading images */
uploadingImages?: Set<string>
/** Callback fired when an image upload starts */
onUploadStart?: (fieldName: string) => void
/** Callback fired when an image upload completes */
onUploadEnd?: (fieldName: string) => void
/** Whether the field is disabled */
disabled?: boolean
}
/**
* Renders the appropriate field component based on the field type
*
* Supports: string, number, boolean, date, array, object, image, rich-text, embed
*
* @component
* @param props - The field renderer props
* @returns The appropriate field component for the given field type
*
* @example
* ```tsx
* <FieldRenderer
* field={field}
* value={formData[field.name]}
* onChange={(value) => handleFieldChange(field.name, value)}
* bucket={bucket}
* />
* ```
*/
export const FieldRenderer: React.FC<FieldRendererProps> = ({ ... }) => {
// Implementation
}/**
* Custom hook for managing operation states in a consolidated way
*
* Replaces multiple boolean state variables with a single state object
*
* @returns Operation state utilities and setters
*
* @example
* ```tsx
* const operations = useOperationState()
*
* // Set operation state
* operations.setCreating('entry')
*
* // Check operation state
* if (operations.isLoading) {
* return <Spinner />
* }
*
* // Reset to idle
* operations.setIdle()
* ```
*/
export const useOperationState = () => {
// Implementation
}/**
* Uploads an image to S3 and generates multiple size variants
*
* @param bucket - The S3 bucket name
* @param base64Data - Base64-encoded image data
* @param filename - Desired filename for the image
* @param contentType - MIME type of the image
* @param width - Original image width in pixels
* @param height - Original image height in pixels
*
* @returns Promise resolving to upload result with all generated variants
*
* @throws {Error} If S3 client is not configured
* @throws {Error} If image upload or processing fails
*
* @example
* ```typescript
* const result = await imageService.uploadImage(
* 'my-bucket',
* base64Data,
* 'photo.jpg',
* 'image/jpeg',
* 1920,
* 1080
* )
*
* if (result.success) {
* console.log('Original URL:', result.result.url)
* console.log('Sizes:', result.result.sizes)
* }
* ```
*/
async uploadImage(bucket: string, base64Data: string, ...): Promise<UploadResult> {
// Implementation
}/**
* Represents a content entry in the CMS
*/
export interface ContentEntry {
/** Unique identifier for the entry */
id: string
/** ID of the schema this entry follows */
schemaId: string
/** ID of the collection this entry belongs to */
collectionId: string
/** Entry metadata (title, description, slug) */
metadata?: {
title?: string
description?: string
slug?: string
}
/** The actual content data matching the schema fields */
data: Record<string, any>
/** Whether this entry is published in the API */
published: boolean
/** ISO timestamp when entry was first published */
publishedAt?: string
/** Tags for categorization */
tags?: string[]
/** ISO timestamp when entry was created */
createdAt: string
/** ISO timestamp when entry was last updated */
updatedAt: string
}- ✅ Document all public APIs
- ✅ Include
@paramfor parameters - ✅ Include
@returnsfor return values - ✅ Add
@examplefor complex usage - ✅ Use
@throwsto document errors - ✅ Keep descriptions concise but clear
- ✅ Use inline comments for complex logic
- ❌ Document obvious getters/setters
- ❌ Over-document internal utilities
- ❌ Write essays (keep it brief)
- ❌ Duplicate information from types
/**
* Brief description (one line)
*
* Longer description if needed (optional)
* Can span multiple lines
*
* @component - For React components
* @param name - Description of parameter
* @returns Description of return value
* @throws {ErrorType} When this error occurs
* @example
* ```tsx
* // Code example here
* ```
*
* @see RelatedComponent - Link to related docs
* @deprecated Use NewComponent instead
*/-
Field Components (src/renderer/components/fields/)
- FieldRenderer ⭐ (most important)
- ImageField (complex upload logic)
- ArrayField (chip UI)
- EmbedField (validation)
-
Hooks (src/renderer/hooks/)
- useOperationState ⭐
- useModalState ⭐
- useContentAPI
- useS3Service
-
Services (src/main/services/)
- contentService (API generation)
- mediaService (asset tracking)
- imageService (image processing)
-
Core Components
- ContentManager (main UI)
- MarkdownEditor (rich text)
- MediaLibrary (asset management)