{# ================================================================================ Documentation Navigation Component (Kida-Native) ================================================================================ Hierarchical sidebar navigation for documentation sites. Uses pre-computed NavTree for optimal performance. KIDA FEATURES USED: - {% def %} for recursive macro (3x faster than {% include %}) - {% let %} for template-scoped variables - Optional chaining (?.) for null-safe access - Null coalescing (??) for smart defaults - {% match %} for node type dispatch - {% spaceless %} for clean HTML output FEATURES: - Hierarchical tree structure via NavTree API - Active page highlighting (automatic via NavNodeProxy) - Active trail marking (automatic via NavTreeContext) - Version-aware filtering (automatic via NavTreeCache) - Keyboard accessible - Section icons from frontmatter USAGE: {% include 'partials/docs-nav.html' %} ================================================================================ #} {# Control icon visibility - defaults to true if not passed in context #} {% let show_nav_icons = show_nav_icons ?? true %} {# ============================================================================= NAV NODE MACRO - Recursive navigation node renderer Replaces the previous docs-nav-node.html include pattern. Macros are compiled once and called as functions, eliminating the per-call overhead of {% include %} (context copy, template lookup). ============================================================================= #} {% def nav_node(item, depth=0) %} {# Extract values once with null-safe access #} {% let item_title = item?.title ?? 'Untitled' %} {% let item_icon = item?.icon ?? '' %} {% let item_href = item?.href ?? '' %} {% let item_children = item?.children ?? [] %} {% let is_current = item?.is_current ?? false %} {% let is_in_trail = item?.is_in_trail ?? false %} {% let is_section = item?.is_section ?? false %} {% let has_children = item_children | length > 0 %} {% match has_children, depth %} {# ===== ROOT NODE (depth 0) - Static header, no toggle ===== #} {% case true, 0 %}
{% if show_nav_icons %} {% spaceless %} {{ icon(item_icon ?? 'folder', size=16) }} {% end %} {% end %} {% if item_href %} {{ item_title }} {% else %} {{ item_title }} {% end %}
{% for child in item_children %} {{ nav_node(child, depth + 1) }} {% end %}
{# ===== EXPANDABLE NODE (depth > 0) - CSS-only accessible toggle ===== #} {# Uses
/ for native toggle + CSS :has() to control sibling visibility. The link is OUTSIDE (as a sibling), avoiding nested interactive elements. CSS Grid arranges: [toggle] [icon] [link] on first row, [items] spanning full width below. #} {% case true, _ %} {# ===== LEAF NODE (no children) ===== #} {% case false, _ %}
{% if item_href %} {% if show_nav_icons and is_section %} {% spaceless %} {{ icon(item_icon ?? 'folder', size=14) }} {% end %} {% end %} {{ item_title }} {% else %} {% if show_nav_icons and is_section %} {% spaceless %} {{ icon(item_icon ?? 'folder', size=14) }} {% end %} {% end %} {{ item_title }} {% end %}
{% end %} {% end %} {# ============================================================================= MAIN NAVIGATION COMPONENT ============================================================================= #} {# Check if page is autodoc - autodoc pages should use scoped navigation #} {% let is_autodoc = is_autodoc_page(page) if is_autodoc_page is defined else false %} {# Always scope docs navigation to the page's section root. The docs-nav template is only used by doc-type pages, so scoped navigation is the expected behavior - docs sidebar should show docs content only, not sibling top-level sections like releases or tracks. nav_root: true metadata can still be used to create navigation boundaries within a section (e.g., /api/python/ stops at itself, not /api/). #} {% let page_section = page?._section %} {% let root_section = page_section?.root ?? none %}