Skip to content

Hierarchical/Level-aware carets for nested list structures #377

@simon5057

Description

@simon5057

Problem Statement

When streaming multi-level lists (common in AI-generated outlines, research summaries, or hierarchical data), the caret indicator always uses the same style regardless of nesting depth. This makes it harder to visually track which indentation level is currently being written.

Image

Current behavior:
The caret (▋ or ●) appears at the end of content but doesn't reflect the list hierarchy.

Desired behavior:
Carets should visually indicate nesting level to match the list structure, similar to how different bullet styles indicate hierarchy.

Proposed Solution

Extend the caret prop to support hierarchical modes or add a caretHierarchy configuration:

Option 1: Extend caret prop types

// Current
caret?: "block" | "circle"

// Proposed
caret?: 
  | "block" 
  | "circle"
  | "hierarchical"      // Auto-match caret to list depth
  | "hierarchical-fade" // + opacity reduction per level
  | CaretLevelConfig;   // Custom per-level definitions

interface CaretLevelConfig {
  0: "block" | "circle" | "line";      // Root level
  1: "block" | "circle" | "line";      // First indent
  2: "block" | "circle" | "line" | "none"; // Second indent
  // or use pattern matching for deeper levels
  default?: "block" | "circle";
  /** Visual weight reduction per level (0-1) */
  opacityStep?: number;
  /** Size reduction in px per level */
  sizeStep?: number;
}

Option 2: Add to existing Options interface

interface Options {
  // ... existing fields
  /**
   * Configure caret appearance based on DOM nesting depth.
   * Only applies when mode="streaming" and isAnimating={true}
   */
  caretHierarchy?: {
    /** Enable level-aware carets */
    enabled: boolean;
    /** 
     * Map indentation levels to caret variants.
     * Level 0 = root list items, Level 1 = first indentation, etc.
     */
    levels?: Array<keyof typeof carets | { 
      style: keyof typeof carets; 
      opacity?: number;
      color?: string;
    }>;
    /** Automatically match caret style to list bullet type (• ○ -) */
    matchBulletStyle?: boolean;
  };
}

Alternatives Considered

Custom CSS targeting .streamdown-caret with :has(> ul > li) selectors, but this requires complex CSS and doesn't handle the streaming state where the caret moves between levels dynamically.

Use Case

Priority

Nice to have

Contribution

  • I am willing to help implement this feature

Additional Context

Built-in themes could include:

  • "academic": Matches the Word/PPT standard hierarchy (solid → hollow → dash → diamond)
  • "minimal": Fading opacity per level (100% → 70% → 40%)
  • "outline": Block → Line → Dot → None

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions