Files
the-custodian/contrib/upstream-prs/2026-02-26--observablehq--framework--toc-sidebar-inject.md
tegwick 0d978b1417 feat(canon): add contribution-convention v0.1, contrib/ templates, and first UPR artifact
- canon/standards/contribution-convention_v0.1.md: master spec for BR/FR/EP/UPR
  artifact types, directory layout, frontmatter schema, ID schemes (EP-DOMAIN-NNN
  for extension points), status lifecycle, and relationship to State Hub
- canon/standards/contrib-templates/: four template files (br, fr, ep, upr)
- contrib/upstream-prs/2026-02-26--observablehq--framework--toc-sidebar-inject.md:
  first real UPR artifact — proposes injectTocTop() to Observable Framework

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 17:28:13 +01:00

100 lines
3.5 KiB
Markdown

---
id: upr-2026-02-26--observablehq--framework--toc-sidebar-inject
type: upr
target_org: observablehq
target_repo: framework
title: "Add injectTocTop() utility for injecting elements into the TOC sidebar"
status: draft
domain: custodian
related_workstream: contribution-tracking-sbom
state_hub_contribution_id: null
created: "2026-02-26"
updated: "2026-02-28"
local_component_path: "state-hub/dashboard/src/components/toc-sidebar.js"
target_upstream_file: "src/client/toc.ts"
upstream_pr_url: null
---
# Upstream PR: Add injectTocTop() utility for injecting elements into the TOC sidebar
## Summary
Propose adding an `injectTocTop(id, element)` utility to Observable Framework
that allows dashboard pages to prepend arbitrary HTML elements at the top of the
automatically-generated table-of-contents sidebar. This enables KPI cards, live
status indicators, and other contextual widgets to live alongside the page's
section links.
## Motivation
Observable Framework generates a TOC sidebar from headings automatically, but
provides no standard way to inject content into it from page JavaScript. As a
result, every project that wants sidebar widgets must implement its own DOM
manipulation workaround.
By upstreaming a small, focused utility, the community gets a stable API for
sidebar injection that doesn't depend on Observable Framework's internal DOM
structure.
## Local Component
**Path in this repo**: `state-hub/dashboard/src/components/toc-sidebar.js`
**Origin story**: Created 2026-02-26 during implementation of the Decisions KPI
dashboard (State Hub v0.2). The component provides two utilities:
- `injectTocTop(id, element)`: remove-then-prepend to the TOC aside element
- `withDocHelp(element, docPath)`: attaches a `?` button that opens a doc page
as an iframe overlay
## Target Upstream Location
**Repo**: `observablehq/framework`
**File**: `src/client/toc.ts` (or a new `src/client/toc-inject.ts`)
## Draft PR Body
```markdown
## Summary
Add `injectTocTop(id, element)` — a small utility for injecting custom elements
at the top of the Observable Framework table-of-contents sidebar.
## Motivation
Dashboard pages frequently need contextual widgets (KPI boxes, live status
indicators, navigation aids) that belong alongside the TOC, not in the page
content flow. Currently this requires each project to directly manipulate the
`#observablehq-toc` DOM element, coupling page code to an internal DOM detail.
`injectTocTop` provides a stable API for this pattern:
```js
import {injectTocTop} from "observablehq:toc";
const myWidget = html`<div class="kpi-box">...</div>`;
injectTocTop("my-kpi-box", myWidget);
```
## Changes
- Add `injectTocTop(id: string, element: HTMLElement): void` to Framework's
client runtime
- Export from the `observablehq:toc` module (or equivalent public API)
- Add documentation page: "Customising the sidebar"
## Testing
- [ ] Unit test: `injectTocTop` prepends element to `#observablehq-toc aside`
- [ ] Unit test: calling again with same `id` removes old element before
inserting new one (idempotent)
- [ ] Integration test: injected element appears above TOC links in rendered page
```
## Notes
- The local implementation (`toc-sidebar.js`) uses `querySelector('#observablehq-toc aside')`
— this should be replaced with a stable API reference once upstreamed.
- The `withDocHelp` utility in the same file is a separate feature; this PR
focuses solely on `injectTocTop`.
- Observable Framework issue tracker should be checked for any existing
discussion of sidebar customisation before opening a new issue.