Skip to content

docs(studio): document timeline keyboard navigation - #3031

Merged
miguel-heygen merged 4 commits into
mainfrom
codex/docs-studio-timeline-accessibility-v2
Aug 5, 2026
Merged

miguel-heygen merged 4 commits into
mainfrom
codex/docs-studio-timeline-accessibility-v2

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Aug 4, 2026 •

Copy link
Copy Markdown
Collaborator

What

Document timeline keyboard navigation, virtualized focus restoration, and screen-reader semantics in the existing Studio guides.

Why

The new interaction path should be discoverable where people already learn timeline editing and look up keyboard commands.

How

The timeline task guide explains the workflow and expected behavior. The shortcuts reference owns the exact command table so the two pages do not duplicate the same job.

This documentation PR targets #2715 and is the stack tip.

Test plan

  • npx mint validate

  • npx mint broken-links --check-redirects

  • git diff --check

  • Unit tests added/updated (documentation-only change)

  • Manual testing performed

  • Documentation updated

miguel-heygen commented Aug 4, 2026 •

Copy link
Copy Markdown
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@miguel-heygen
miguel-heygen force-pushed the codex/docs-studio-timeline-accessibility-v2 branch from e28b1b5 to 7b6247f Compare August 4, 2026 21:00
@miguel-heygen
miguel-heygen force-pushed the codex/studio-timeline-f-keyboard-controls-v2 branch from 58898e2 to 204a84f Compare August 4, 2026 21:00
@miguel-heygen
miguel-heygen force-pushed the codex/docs-studio-timeline-accessibility-v2 branch from 7b6247f to 479d62e Compare August 4, 2026 21:38
@miguel-heygen
miguel-heygen force-pushed the codex/studio-timeline-f-keyboard-controls-v2 branch from 204a84f to fc6a7b5 Compare August 4, 2026 21:38
@miguel-heygen
miguel-heygen force-pushed the codex/docs-studio-timeline-accessibility-v2 branch from 479d62e to f86eb06 Compare August 4, 2026 21:45
@miguel-heygen
miguel-heygen force-pushed the codex/studio-timeline-f-keyboard-controls-v2 branch 2 times, most recently from f43c86c to be24c54 Compare August 4, 2026 21:52
@miguel-heygen
miguel-heygen force-pushed the codex/docs-studio-timeline-accessibility-v2 branch from f86eb06 to 795b0c4 Compare August 4, 2026 21:52
@miguel-heygen
miguel-heygen marked this pull request as ready for review August 4, 2026 22:00

@vanceingalls vanceingalls left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R1 review at head 795b0c448.

Claims audited against code at #2715 head be24c5412:

Doc claim Code Verdict
Tab into timeline; one roving target TimelineTrackRow tabIndex={rovingTargetId===id?0:-1} Match
Left/Right = prev/next item in row resolveTimelineNavigationTarget ArrowLeft/Right branches Match
Up/Down = nearest-time in adjacent row nearestTarget() sort by Math.abs(time - target.time) Match
Home/End = start/end of row boundaryRow.items.at(-1) ?? boundaryRow Match (Home→row, End→last item; conceptual "start/end" is fair)
Ctrl/Cmd + Home/End = first/last logical row timelineBoundary branch returns boundaryRow directly (Miguel R2 fix) Match — correctly last row, not last item of last row
Page Up/Down = visible page, focus-anchored viewportPageSize uses focusedRow as anchor Match
Enter/Space = expand/collapse track row event.key === "Enter" / " " + expandable → onToggleRow Match
Context Menu / Shift+F10 = context menu event.key === "ContextMenu" or F10+shift → openContextMenu Match
Off-viewport target scrolls + restores focus resolveTimelineFocusFallback chain Match
Treegrid role, track level/expanded TimelineLanes role="treegrid"; TimelineTrackRow aria-level/aria-expanded Match
Clips/keyframes/ease announce names, times, selection TimelineClip aria-label+aria-pressed; TimelineClipDiamonds keyframe aria-label+aria-pressed; TimelineDiamondConnectors ease aria-label Match

Non-blocking nit (follow-up): APG disclosure arrows shipped in #2715 R2 — on an expandable track row, ArrowRight expands and ArrowLeft collapses (useTimelineKeyboardActor lines guarding event.key === "ArrowRight/Left" + expandable). The docs only mention Enter/Space for that toggle. Both work; adding a sentence would help WAI-ARIA-familiar users. Won't block on docs-only PR.

No emojis. No stale aria-multiselectable references. Table matches switch-statement. Tab into the timeline correctly avoids the non-Tab-header-key anti-pattern Miguel called out.

— Review by Via

@james-russo-rames-d-jusso james-russo-rames-d-jusso left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 795b0c448. Docs-only, 28 additions across docs/studio/shortcuts.mdx (new "Timeline navigation" section with a 7-row shortcut table) and docs/studio/timeline.mdx (5 prose paragraphs + a cross-link back to the shortcuts anchor). Verified every user-visible claim against the code shipped in #2715 at be24c5412 — each keybinding, ARIA semantic, and roving-focus statement traced to file:line.

Three concerns worth inline. All non-blocking; all about docs undershooting or overshooting the shipped code.

Verified end-to-end:

  • ✅ Shortcut table keybindings match the actor:

    • ArrowLeft/Right within a row → timelineKeyboardNavigation.ts:274-277,281
    • ArrowUp/Down → nearest-time item on the neighbor row (:293)
    • Home / End (unmodified) → row boundary (:270-272)
    • Ctrl+Home / Ctrl+End (or Cmd on Mac) → first / last logical row (:271-272); event.ctrlKey || event.metaKey at the actor (useTimelineKeyboardActor.ts:100) makes both modifiers universal
    • PageUp/Down → uses viewportPageSize (focus-anchored, useTimelineKeyboardActor.ts:28-49)
    • Enter / Space on expandable row → onToggleRow (useTimelineKeyboardActor.ts:107-116)
    • Context Menu / Shift+F10 → synthesized contextmenu MouseEvent at target center (useTimelineKeyboardActor.ts:120-135)
  • ✅ role="treegrid" is set — TimelineLanes.tsx:153. (Impl detail: it's on the inner TimelineLanes wrapper, not on the overflow-x-auto/overflow-y-auto scroll container at Timeline.tsx:462. Reader-facing statement is still accurate; scroll behavior + AT semantics live on different elements by design.)

  • ✅ aria-level + aria-expanded — TimelineTrackRow.tsx:52-53 (aria-level unconditional, aria-expanded correctly gated on logicalRow.expandable); property sub-rows also carry aria-level at :71; disclosure caret carries aria-expanded at LayerDisclosureRow.tsx:48.

  • ✅ Clips: aria-label with time + aria-pressed — TimelineClip.tsx:102-103.

  • ✅ Keyframes: aria-label with time + aria-pressed — TimelineClipDiamonds.tsx:346-347.

  • ✅ Off-screen focus reveal — the #2714 focus coordinator + pin from pinnedRowKeys / pinnedClipIdentities keeps the focused target mounted; scroll + focusElement in the useEffect. Doc's "mounts it, scrolls it into view, and then restores focus" reads accurately (though the actual order is pin → mount via virtualRows → scroll → focus; user-facing description is fine).

  • ✅ Anchor /studio/shortcuts#timeline-navigation — Mint config in docs/docs.json has no slug rules; default kebab-case-lowercase applies. ## Timeline navigation → #timeline-navigation. mint broken-links in the test plan will catch any regression.

Body-only nit:

  • timeline.mdx:58 — "Studio mounts it, scrolls it into view, and then restores focus" actually runs "pin → mount via virtualized row set → scroll into view → focus" — the pin comes first, and it's what keeps the target mounted long enough for the scroll+focus to succeed. Not worth changing the doc — the ordering-of-verbs is user-facing correct — but if a future edit tightens this, "pins" (or "keeps mounted") is the invariant the reader should carry into the code.

Test plan (mint validate, mint broken-links, git diff --check) is well-scoped for docs. CI at HEAD is all-pass except Graphite / mergeability_check (in-progress, standard) and Mintlify Deployment (skipping — expected on this PR shape).

Ready from where I sit once the three inline concerns are considered — most impactful is the easing-selection-state overclaim on timeline.mdx:61, since fixing it is a one-word edit ("names and times" instead of "names, times, and selection state"). Leaving as COMMENTED.

— Review by Rames D Jusso

Comment thread docs/studio/timeline.mdx Resolved
Comment thread docs/studio/timeline.mdx Resolved
Comment thread docs/studio/shortcuts.mdx Resolved
@miguel-heygen
miguel-heygen force-pushed the codex/docs-studio-timeline-accessibility-v2 branch from 795b0c4 to c6d632f Compare August 4, 2026 22:41
@miguel-heygen
miguel-heygen force-pushed the codex/studio-timeline-f-keyboard-controls-v2 branch from be24c54 to 16d27c2 Compare August 4, 2026 22:41
@miguel-heygen
miguel-heygen force-pushed the codex/docs-studio-timeline-accessibility-v2 branch from c6d632f to 1969a47 Compare August 4, 2026 22:47
@miguel-heygen

Copy link
Copy Markdown
Collaborator Author

All docs review follow-ups are folded into exact head 1969a47d8: disclosure and parent-row arrows are documented, the roving target is correctly scoped to logical targets while native header controls remain Tab stops, and easing controls no longer overclaim selection state. Mint validation and broken-link checks pass; all inline threads are replied to and resolved.

vanceingalls
vanceingalls previously approved these changes Aug 4, 2026

@vanceingalls vanceingalls left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

R2 delta at 1969a47d8. Three doc changes vs my R1 stamp at 795b0c448, all closing Rames's R1 concerns and my own APG-arrow follow-up:

  • shortcuts.mdx +1 paragraph after the table: ArrowRight expands / ArrowLeft collapses an expandable track row; ArrowLeft from a keyframe property row returns to parent; otherwise arrows move within the row.
  • timeline.mdx:56 — Enter/Space sentence expanded to also cover Right-to-expand, Left-to-collapse, Left-to-parent.
  • timeline.mdx:58 — "one keyboard target" → "one logical timeline target", plus explicit note that native header controls remain separate Tab stops.
  • timeline.mdx:60 — clips/keyframes split from easing (easing loses "selection state").

All four re-verify against #2715 code:

  • useTimelineKeyboardActor.ts:97-105 — kind === "row" && expandable short-circuit for ArrowRight/Left → onToggleRow.
  • timelineKeyboardNavigation.ts:274-276 — ArrowLeft on collapsed level-2 row → parentId.
  • TimelineTrackHeader.tsx — VisibilityButton, prev/next-keyframe chevrons, add/remove-keyframe: native <button> with no tabIndex override, so header controls do stay in the Tab order alongside the roving logical target.
  • TimelineDiamondConnectors.tsx:181-182 — ease control has aria-label (name + time) but no aria-pressed.

Required checks (HF ruleset 14211637, 8): regression SUCCESS; other 7 (Semantic PR title, Test: runtime contract, Typecheck, Build, Test, Render on windows-latest, Tests on windows-latest) NOT_RUN — expected for a docs-only PR on the stack tip. mergeStateStatus: UNSTABLE is just Graphite mergeability_check in progress. Base is the stack branch codex/studio-timeline-f-keyboard-controls-v2; retarget to main before land.

Docs match code, R1 gaps closed. No new findings.

— Review by Via

@miguel-heygen
miguel-heygen changed the base branch from codex/studio-timeline-f-keyboard-controls-v2 to main August 4, 2026 23:26
@miguel-heygen
miguel-heygen dismissed vanceingalls’s stale review August 4, 2026 23:26

The base branch was changed.

@miguel-heygen
miguel-heygen force-pushed the codex/docs-studio-timeline-accessibility-v2 branch from 1969a47 to 19070b5 Compare August 4, 2026 23:56
@mintlify

mintlify Bot commented Aug 4, 2026 •

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
hyperframes 🟢 Ready View Preview Aug 4, 2026, 11:57 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@vanceingalls vanceingalls left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delta re-verify at head 19070b52d (Family F consolidated tip on main).

Rebase context: After #2711 + #2712 squash-merged, Miguel rebased #3031 onto current main. PR now carries 4 commits:

  1. feat(studio): expose timeline treegrid semantics — #2713 content (prior stamp 15ef84ca1 / 415548272)
  2. feat(studio): coordinate logical timeline focus — #2714 content (prior stamp 21b2c9149)
  3. feat(studio): add timeline keyboard controls — #2715 content (prior stamp 16d27c28c)
  4. docs(studio): document timeline keyboard navigation — docs (prior stamp 1969a47d8)

Content match: Consolidated diff (41 files, +1905/-647) is the union of the four already-stamped bodies — lanesIdPrefix / timelineLogicalRowCellId / rowgroup>row refactor / aria-colcount+colindex / expandable (#2713); logical timelineFocus.id model / tabIndex={-1} / appliedRef self-heal / resolveTimelineFocusFallback deletion / getRowTop scroll geometry / focus tests / O(1) focusElement via CSS.escape / dropped aria-multiselectable (#2714); Arrow/Home/End/Page bindings / APG disclosure ArrowRight-expand / Ctrl+End→last / Enter/Space toggle + native-click assertion / ContextMenu+Shift+F10 / dataset.timelineFocusId Tab-bail / rovingTargetId-gated tabIndex / viewportPageSize memo (#2715); shortcuts.mdx + timeline.mdx APG arrows + parent-jump + native-header Tab access + selection-vs-easing split (#3031 docs).

Review threads: All 3 doc threads from Rames D Jusso resolved by Miguel (easing selection-state phrasing, "logical timeline target" scoping, expand/collapse row-vs-item table split).

Required-checks state (ruleset 14211637):

  • Build: IN_PROGRESS
  • Render on windows-latest: IN_PROGRESS
  • Semantic PR title: SUCCESS
  • Test: not surfaced by name in this rollup (Producer: unit/integration tests IN_PROGRESS)
  • Test: runtime contract: IN_PROGRESS
  • Tests on windows-latest: IN_PROGRESS
  • Typecheck: IN_PROGRESS
  • regression: SUCCESS

mergeStateStatus: BLOCKED — CI still restarting per Miguel. Approve stands on the consolidated content match; land only after all 8 required checks turn SUCCESS.

Review by Via

@james-russo-rames-d-jusso james-russo-rames-d-jusso left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 19070b52d — tip-only carve-out landing strategy.

Delta from my prior fully-approved cumulative tree (1969a47d8):

All 41 files in the current #3031 diff have byte-identical blob SHAs between 1969a47d8 and 19070b52d. Zero content changes; the rebase relocated the four remaining Family F commits (#2713-scope + #2714-scope + #2715-scope + docs) onto current main without touching the tree.

New commit stack sitting cleanly on top of main at 0f1333c80 (squash-merge of #2712):

  • fd520d3a feat(studio): expose timeline treegrid semantics (was #2713 @ 415548272)
  • f2819fa6 feat(studio): coordinate logical timeline focus (was #2714 @ 21b2c9149)
  • fccb4261 feat(studio): add timeline keyboard controls (was #2715 @ 16d27c28c)
  • 19070b52 docs(studio): document timeline keyboard navigation (was docs @ 1969a47d8)

Files that dropped out of the diff are all now-landed #2711/#2712 or External-change-stack scope (playerStore.ts, liveTime.ts, useSdkSession.ts, usePreviewPersistence.ts, externalFileReloadBus.ts, useStudioExternalFileChanges.ts, App.tsx, DesignPanelPromoteProvider.tsx, ExternalFileConflictBanner.tsx, scripts/ci/install-workspace-dependencies.sh, .github/workflows/ci.yml, …). Their state at 19070b52d = state at main; no drift.

Cumulative content is exactly what I signed off at 1969a47d8. LGTM from my side — safe to re-stamp this as the tip-only landing candidate.

— Review by Rames D Jusso

@miguel-heygen
miguel-heygen merged commit 7bf425b into main Aug 5, 2026
47 checks passed
@miguel-heygen
miguel-heygen deleted the codex/docs-studio-timeline-accessibility-v2 branch August 5, 2026 00:09

This branch was successfully deployed

1 active deployment
staging - docs — 19070b52 Deployed Aug 4, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants