Component Contract

In-page Nav (Table of Contents)

A vertical “On this page” anchor list that tracks the reader's position in long-form content.

Live Demo

Rendered

First link shown as the current section (.active).

1. Summary

Component nameIn-page Nav (Table of Contents)
AEM resource typecaat/components/in-page-nav
TierBase — composes nothing but tokens
PurposeAn anchor list to page sections, highlighting the current one as the reader scrolls. Reusable on any long page (articles, policy, guides).
VariantsDefault · Sticky (--sticky)
Status New
Replaces.caat-article__toc (article-internal)

Used by

  • Article Layout — sidebar table of contents.
  • Any long-form page (policy, guides, FAQ) needing section wayfinding.

2. Design Tokens

TokenRole
--caat-color-bg-page / --caat-color-borderCard surface + border
--caat-color-textLink (resting)
--caat-color-text-link-hoverLink hover + active accent rule
--caat-color-text-headingTitle + active link text
--caat-color-state-selected-subtleActive link background
--caat-color-focus-ring / outlineFocus indicator

3. Authoring Fields

FieldTypeRequiredNotes
TitleTextNoDefault "On this page"
SourceSelectYesAuto (from page headings) · Manual list
Items (manual)MultifieldConditionalLabel + anchor target
StickyCheckboxNoPins the nav while scrolling (when standalone)

4. Validation Rules

No author-managed content beyond an accessible label, so there are no authoring validation rules. Accessibility requirements are covered in Section 8 (Accessibility).

5. Content Guidance

  • Use for pages longer than ~3 screens with clear section headings.
  • Mirror the page's <h2> headings; keep labels short.
  • Don't duplicate the global navigation — this is within-page wayfinding only.

6. Semantic HTML

<div class="caat-in-page-nav" data-bs-spy="…">
  <p class="caat-in-page-nav__title">On this page</p>
  <nav class="nav flex-column" aria-label="On this page">
    <a class="nav-link active" href="#calculated">How your pension is calculated</a>
    <a class="nav-link" href="#retirement">When can you retire?</a>
  </nav>
</div>

Use Bootstrap Scrollspy to toggle .active on the current section's link automatically.

7. CSS Contract

SelectorPurpose
.caat-in-page-navCard wrapper (surface, border, padding)
.caat-in-page-nav--stickyPins to top: 5rem while scrolling
.caat-in-page-nav__titleUppercase section heading
.caat-in-page-nav .nav-linkAnchor link; .active shows current section (left accent + subtle bg + bold)
:hover · :focus-visibleStates

8. Accessibility

RequirementImplementation
LandmarkWrap links in <nav aria-label="On this page"> so it's a distinct, named landmark.
Current sectionActive link carries aria-current="true" (in addition to .active), and is not signalled by colour alone (left accent + weight).
Keyboard / focusNative anchors; visible :focus-visible outline.
Target sizeComfortable link padding meets the 24px target.

9. SEO

Transient / structural UI with no indexable content of its own — no SEO markup required. Ensure any content this component wraps or reveals stays server-rendered and crawlable.

10. Analytics

Analytics are captured through the shared data-analytics-component attribute on the component root (emitted automatically) and reported to the central data layer. Event names and payloads follow the organisation's standard analytics schema — defined centrally with the analytics team, not invented per component — so no bespoke tracking is specified here.

11. AEM Implementation Notes

  • Resource type: caat/components/in-page-nav.
  • Auto mode: a Sling model harvests <h2> ids from the page's content tree; manual mode reads an items multifield.
  • Bootstrap Scrollspy is initialised on the article body container.

12. Dialog Model (cq:dialog)

Not authored directly. The in page nav is a sub-element emitted and configured by its host component (or generated from page structure), so it has no standalone cq:dialog — any options are exposed through the host component's dialog.

13. QA Checklist

#CheckPass?
1Active link tracks the scrolled section (scrollspy)
2Current section signalled by accent + weight, not colour alone
3Wrapped in a labelled <nav> landmark
4Keyboard focus ring visible on each link
5Every anchor resolves to a real page id

14. Definition of Done

  • Styling token-driven — no hard-coded colours.
  • Scrollspy wired; active state + aria-current verified.
  • article-layout refactored to consume it (was .caat-article__toc).
  • Accessibility audit — landmark, focus, colour-independence.
  • QA checklist signed off.