Skip to content

Add a sticky table of contents to lesson pages #131

Description

@ebouchut

Need

Lesson pages have no table of contents: readers of long lessons cannot
see the structure or jump to a section, and there are no heading
anchors to deep-link to.

Design

See ADR-0018

Hybrid, per the discussion and wireframe review:

  • Server: a post-sanitization pass in the renderer mints slugified
    anchor ids on h2..h4 and returns the TOC entries alongside the
    HTML.
    Ids are minted by our code AFTER sanitization, so
    author-supplied ids still die (the sanitizer strips id today, and
    that protects the #main skip-link target).
    The allowlist does not change, and spoofing stays structurally impossible.
  • Template: a details/summary TOC inside nav aria-label="Contents",
    rendered when the lesson has at least 2 entries.
    Sticky: a pinned sidebar on desktop (internal scroll for long TOCs)
    and a slim pinned collapsed bar on mobile, so the TOC is
    viewable at any scroll position. Works without JavaScript.
  • Client: lesson-toc.js auto-opens the panel on wide screens and
    adds an IntersectionObserver scroll-spy that marks the current
    section with aria-current (CP4: dynamic interface).

Acceptance criteria

  • Lessons with 2+ headings show the TOC; anchor links jump to the
    section and update the URL hash; single-heading lessons show none.
  • The TOC is viewable at any scroll position, desktop (pinned
    sidebar) and mobile (pinned collapsed bar), with no horizontal
    page scroll.
  • Without JavaScript, the TOC is present, sticky, and expandable
    (MockMvc pins the server-rendered nav and anchors).
  • Author-supplied ids in raw HTML are stripped; minted slugs fold
    accents and deduplicate repeated headings.
  • Scroll-spy moves aria-current across TOC links while scrolling.
  • axe (WCAG 2.1 A/AA) reports no new violations in both themes;
    full test suite and Checkstyle stay green.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions