Files
remorses__playwriter/docs
Tommy D. Rossi 21cfadce7d feat(website): refactor TOC to recursive tree with multi-page support
Replace flat TocItem/PreparedTocItem/TocGroup types with a recursive
TocTreeNode -> FlatTocItem pipeline that supports arbitrary page nesting.

**Types:**
- TocNodeType = 'page' | 'h1'-'h6' — heading level encoded in type field,
  no separate headingDepth. Smaller objects, self-descriptive.
- TocTreeNode = { label, href, type, children } — recursive tree, the wire format.
- FlatTocItem = { label, href, type, visualLevel, prefix, parentHref, pageHref }
  — flat rendering item with depth clamped to 0-3.

**Depth clamping:**
flattenTocTree() walks the recursive tree and clamps visual depth to max 4
levels (0-3). When pages nest deeply, headings flatten to siblings at level 3.
Formula: visualLevel = min(pageDepth + headingDepth, 3). Preserves correct
visual gap for skipped markdown levels (## -> ####) via the h-type encoding.

**Component changes:**
- TableOfContents accepts FlatTocItem[], renders with visibility filtering
  instead of two-tier TocGroup. Expand/collapse works at any depth by
  tracking expanded hrefs and computing visibility from parentHref chain.
- Search expand override merged into visibility computation so matched items
  inside collapsed branches become visible during search.
- search.ts operates directly on FlatTocItem[] — removed SearchEntry and
  buildSearchEntries(). Walks parentHref chain for ancestor expansion.

**Extraction:**
slugify, extractText, generateTocTree moved to toc-tree.ts (side-effect-free)
so they can be tested without importing the page module.

**Tests:**
21 vitest tests covering slugify, extractText, tree building (nested, skipped
levels, pop-back), flattening (prefixes, depth clamping, page wrapping,
parentHref/pageHref tracking), and full mdast -> tree -> flat pipeline.

**Remaining for multi-page:**
- Multi-page data source (multiple MDX files / manifest)
- Route-aware active tracking (pathname for page, IntersectionObserver for
  headings on current page only)
- Cross-page navigation (SPA or full page load)
2026-03-28 15:03:05 +01:00
..
2026-02-22 15:21:38 +01:00
2026-02-26 21:18:43 +01:00