laconic-deployer-frontend/standards/documentation/COMPONENT_DOCUMENTATION.md

12 KiB

Component Documentation Standards

This document outlines the documentation standards for components across the entire project. Following these standards ensures consistency and makes the codebase more maintainable.

TypeScript Documentation Approach

This project uses a TypeScript-first documentation approach, focusing on TypeScript's native documentation capabilities rather than traditional JSDoc. While TypeScript supports JSDoc syntax, we prioritize TypeScript-specific documentation patterns where possible.

TSDoc vs JSDoc

  • TSDoc is a documentation standard specifically designed for TypeScript
  • We prefer TypeScript's native type annotations over JSDoc type annotations
  • Use explicit type definitions in code instead of JSDoc type comments when possible
  • When JSDoc-style comments are needed, use TypeScript-compatible JSDoc tags

Documentation Tools

Our documentation approach is designed to work well with:

  • TypeScript's built-in type checking
  • IDE integrations like VS Code's IntelliSense
  • Documentation generators that support TypeScript

TypeScript-Specific Documentation Tags

/**
 * This function demonstrates TypeScript-native documentation
 *
 * @remarks
 * The remarks section provides additional details that wouldn't fit in the brief description.
 *
 * @typeParam T - Generic type parameter for the input array
 * @typeParam U - Generic type parameter for the output array
 *
 * @param items - Array of items to process (TypeScript infers the type)
 * @param mapper - Function to transform items (TypeScript infers the signature)
 * @returns Array of transformed items
 *
 * @example
 * ```ts
 * // Transform numbers to strings
 * const numbers = [1, 2, 3];
 * const strings = mapItems(numbers, n => n.toString());
 * ```
 */
function mapItems<T, U>(items: T[], mapper: (item: T) => U): U[] {
  return items.map(mapper);
}

/**
 * Interface for configuration options
 *
 * @public
 */
export interface ConfigOptions {
  /**
   * Base URL for API requests
   */
  apiUrl: string;

  /**
   * Authentication token
   * @defaultValue undefined
   */
  token?: string;

  /**
   * Request timeout in milliseconds
   * @defaultValue 3000
   */
  timeout: number;
}

Component JSDoc Template

/**
 * @component ComponentName
 * @description Brief description of what the component does
 *
 * @see [Optional] Link to design reference (e.g., Figma)
 *
 * [Optional: Additional context about the component's role in the application]
 *
 * @example
 * ```tsx
 * <ComponentName prop1="value" prop2={value} />
 * ```
 *
 * @dependencies
 * - DependencyComponent1
 * - DependencyComponent2
 */

Props Interface Template

/**
 * Props for the ComponentName component
 * @interface ComponentNameProps
 * @property {Type} propName - Description of the prop
 * @property {Type} [optionalProp] - Description of the optional prop
 * @property {() => void} [onEvent] - Callback fired when event occurs
 */
interface ComponentNameProps {
  propName: Type;
  optionalProp?: Type;
  onEvent?: () => void;
}

Function Template

/**
 * Description of what the function does
 * @function functionName
 * @param {ParamType} paramName - Description of the parameter
 * @returns {ReturnType} Description of the return value
 * @throws {ErrorType} Description of potential errors
 */
function functionName(paramName: ParamType): ReturnType {
  // Implementation
}

Type/Interface Template

/**
 * Description of what this type/interface represents
 * @interface InterfaceName
 * @property {Type} propertyName - Description of the property
 * @property {Type} [optionalProperty] - Description of the optional property
 */
interface InterfaceName {
  propertyName: Type;
  optionalProperty?: Type;
}

/**
 * Description of this type alias
 * @type TypeName
 */
export type TypeName = BaseType & {
  additionalProperty: string;
};

/**
 * Type for use with generic components
 * @template T - Description of the generic parameter
 */
export type GenericType<T> = {
  value: T;
  label: string;
};

Enum Template

/**
 * Description of what this enum represents
 * @enum {string|number} EnumName
 */
export enum EnumName {
  /**
   * Description of this enum value
   */
  VALUE_ONE = 'value_one',

  /**
   * Description of this enum value
   */
  VALUE_TWO = 'value_two',
}

Const Assertion Template

/**
 * Description of this constant object
 * @const objectName
 */
export const objectName = {
  PROPERTY_ONE: 'value_one',
  PROPERTY_TWO: 'value_two',
} as const;

/**
 * Type derived from const assertion
 * @type TypeFromConst
 */
export type TypeFromConst = (typeof objectName)[keyof typeof objectName];

Import/Export Type Guidelines

When working with TypeScript, use explicit type imports/exports for better clarity:

// Preferred: Explicit type imports
import type { SomeType, AnotherInterface } from './types';
import { Component } from './components';

// Preferred: Explicit type exports
export type { ComponentProps } from './Component';
export { Component } from './Component';

// For re-exporting both the type and value:
export { default as Component, type ComponentProps } from './Component';

Barrel File (index.ts) Template

/**
 * @module ModuleName
 * @description Brief description of the module's purpose
 *
 * This barrel file exports all public components, hooks, and types from the module.
 * When importing from this module, use the following pattern:
 * ```tsx
 * import { ComponentA, ComponentB, useFeature } from '@/path/to/module';
 * ```
 */

// Component exports
export { ComponentA } from './ComponentA';
export { ComponentB } from './ComponentB';

// Hook exports
export { useFeatureA } from './hooks/useFeatureA';
export { useFeatureB } from './hooks/useFeatureB';

// Type exports - use explicit type exports
export type { ComponentAProps } from './ComponentA';
export type { ComponentBProps } from './ComponentB';

// Enum exports
export { FeatureEnum } from './types';

// Re-export all from a sub-module (use sparingly)
export * from './submodule';

Component with Subcomponents Template

/**
 * Parent component description
 * @component ParentComponent
 * @description Overview of the parent component
 *
 * @see [Optional] Link to design reference
 *
 * Component Hierarchy:
 * - ParentComponent
 *   - SubComponent1
 *   - SubComponent2
 *     - NestedComponent
 *
 * @example
 * ```tsx
 * <ParentComponent prop1="value" prop2={value} />
 * ```
 */
export function ParentComponent({ prop1, prop2 }: ParentComponentProps) {
  // Implementation
}

/**
 * Subcomponent description
 * @component SubComponent
 * @description Overview of the subcomponent
 * @private Only used within ParentComponent
 */
function SubComponent({ subProp }: SubComponentProps) {
  // Implementation
}

Hooks Template

/**
 * Description of what the hook does and when to use it
 * @hook useHookName
 *
 * @example
 * ```tsx
 * const { value, setValue } = useHookName(initialValue)
 * ```
 *
 * @param {ParamType} initialValue - Description of the parameter
 * @returns {ReturnType} Description of the return value
 */
function useHookName(initialValue: ParamType): ReturnType {
  // Implementation
}

Store Documentation Template

/**
 * Description of what the store manages
 * @store storeName
 *
 * @example
 * ```tsx
 * const { value, setValue } = useStore()
 * ```
 *
 * State Management:
 * - value: Description of state value
 * - setValue: Description of state updater
 */

Additional Guidelines

  1. Be concise but complete - Provide enough information to understand the component without overwhelming the reader
  2. Document public API - Focus on documenting the public API rather than implementation details
  3. Keep examples simple - Examples should demonstrate common use cases
  4. Update documentation - Keep documentation in sync with code changes
  5. Document side effects - Clearly document any side effects or behaviors that might not be obvious

When to Document

  • All components, hooks, and utilities exported from a package or module
  • Complex internal functions that are difficult to understand at a glance
  • Props, especially those with non-obvious behavior
  • State management code and side effects

TypeScript-Specific JSDoc Tags

TypeScript supports JSDoc with additional TypeScript-specific tags. Use these tags to enhance your documentation:

/**
 * @typeParam T - Type parameter description (preferred over @template)
 * @param param - Parameter with TypeScript type inference (no need for {type})
 * @returns Return value with TypeScript type inference
 * @defaultValue Default value for a property
 * @public Indicates this is part of the public API
 * @private Indicates this is a private member
 * @protected Indicates this is a protected member
 * @readonly Indicates this is a readonly property
 * @deprecated Indicates this is deprecated with optional explanation
 */

// Property documentation in interfaces/classes
interface Example {
  /**
   * Property description
   * @defaultValue 'default'
   */
  property: string;
}

// Documentation for React component props using type alias
type ButtonProps = {
  /**
   * The button's variant style
   * @defaultValue 'primary'
   */
  variant?: 'primary' | 'secondary' | 'tertiary';

  /**
   * Content to display inside the button
   */
  children: React.ReactNode;

  /**
   * Called when the button is clicked
   */
  onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
};

/**
 * Function documentation using modern TypeScript patterns
 *
 * @deprecated Use newFunction instead
 * @throws Error when input is invalid
 */
function oldFunction(input: string): void {
  // Implementation
}

Mermaid Diagrams

Use Mermaid diagrams to visualize complex relationships, flows, or processes. Include Mermaid diagrams directly in markdown documentation using the following formats:

Component Relationship Diagram

/\*\*

- @component ComplexFeature
- @description A complex feature with multiple components
-
- ## Component Relationships
- ```mermaid

  ```

- graph TD
- A[ParentComponent] --> B[ChildComponent1]
- A --> C[ChildComponent2]
- B --> D[GrandchildComponent1]
- B --> E[GrandchildComponent2]
- C --> F[GrandchildComponent3]
- ```
  */
  ```

Data Flow Diagram

/\*\*

- @module DataFlow
- @description Shows how data flows through the application
-
- ## Data Flow
- ```mermaid

  ```

- graph LR
- API[API] --> Store[Store]
- Store --> ComponentA[Component A]
- Store --> ComponentB[Component B]
- ComponentA --> User[User Interface]
- ComponentB --> User
- ```
  */
  ```

State Machine Diagram

/\*\*

- @component StatefulComponent
- @description Component with complex state transitions
-
- ## State Machine
- ```mermaid

  ```

- stateDiagram-v2
- [*] --> Idle
- Idle --> Loading: fetch()
- Loading --> Success: data received
- Loading --> Error: error thrown
- Error --> Loading: retry()
- Success --> Idle: reset()
- Error --> Idle: reset()
- ```
  */
  ```

Sequence Diagram

/\*\*

- @function authenticateUser
- @description Authentication process flow
-
- ## Authentication Sequence
- ```mermaid

  ```

- sequenceDiagram
- participant User
- participant Client
- participant API
- participant Database
-
- User->>Client: Enter credentials
- Client->>API: POST /auth/login
- API->>Database: Validate credentials
- Database-->>API: Valid user
- API-->>Client: JWT token
- Client-->>User: Login success
- ```
  */
  ```

When to Use Mermaid Diagrams

  • Component hierarchy diagrams for complex nested components
  • Data flow diagrams for state management patterns
  • Process flows for complex business logic
  • State machines for components with multiple states
  • Sequence diagrams for asynchronous operations

Mermaid Diagram Guidelines

  1. Keep diagrams simple and focused on one aspect of the system
  2. Use consistent naming conventions in diagrams
  3. Add concise labels to explain relationships
  4. Include a brief text description above each diagram
  5. For complex diagrams, consider breaking them into multiple smaller diagrams