Skip to content

docs(spec): AppShell region plugins and Focus Mode - #8410

Draft
humbertovirtudes wants to merge 1 commit into
mainfrom
docs/app-shell-region-plugins-4255
Draft

humbertovirtudes wants to merge 1 commit into
mainfrom
docs/app-shell-region-plugins-4255

Conversation

@humbertovirtudes

Copy link
Copy Markdown
Contributor

Exact decision needed

Refs #4255. This is a specification-only draft for AppShell's region-transform plugin API and its first Focus Mode plugin. It does not implement or close the feature.

The caller knows whether otherwise identical page content is part of ordinary navigation or a focused task. Removing navigation slots loses state; styling alone cannot coordinate generated drawers, native modal close, and focus. The candidate keeps that task intent at the shell boundary.

Owner decisions remain explicit in OQ1-OQ4: region descriptor and ordering admission, the single preset, effect lifecycle without React Activity on the supported React floor, and restoration of requested drawer state.

Existing authority searched

The distinct system boundary is coordination between AppShell visibility, a cooperating MobileNav's native modal lifecycle, and focus handoff to page content. AppShell remains the aggregate API owner; Focus Mode's independent contract belongs to its module. The current canonical owners must receive the approved projections before build.

Decision

Candidate contract:

  • Optional named plugins with all six transforms from the issue, using shell-owned region descriptors rather than requiring particular child components in ReactNode slots.
  • Canonical focusMode first, then custom own-entry order; region writes compose forward and the last write wins. The first context wrapper is outermost, matching Table.
  • One controlled focus preset hides top/side/mobile navigation and preserves banner, content, padding and independent SideNav state.
  • Retained hidden state, safe later transitions, settled first paint/hydration, reduced motion and existing theme ownership.
  • A cooperating drawer closes natively, releases page inertness, avoids restoring a hidden opener, hands focus to main, and only then suspends through Activity. Independently controlled or portalled custom modals remain caller-owned.
  • Effective public mobile context remains distinct from requested openness. Absent-slot transforms, explicit mobile disable, custom use of the canonical key and reversal cases are specified.

No owner decision is recorded by this draft.

Rejected alternatives

A dedicated focus-mode prop or independent hide props creates a second mechanism instead of the selected plugin direction. Child-component props cannot represent arbitrary existing node slots. Conditional removal loses navigation state; a fragment-only visibility fallback leaves navigation interactive. More presets, augmentation, motion tuning and shortcuts need separate caller-need evidence.

Claim scope and non-goals

Specification records only. No runtime implementation, exports, stories, changesets, theme targets, consumer-doc changes, SideNav collapse/resize changes, or unrelated shell repairs. Main content and its skip target remain available.

Evidence and implementation relationship

The record is grounded in current source and existing canonical contracts. Its verification matrix describes required future evidence, not completed feature tests. An independent critique informed the native-modal focus sequence, custom-drawer cooperation boundary, effective context state, absent/disabled slot cases and Table-compatible context order.

Implementation remains held until exact-text owner decisions are recorded as current authority.

Writing rubric results

  • R1 narration: approval/projection process was removed from the record's intent and impact text; the draft boundary and present-tense behavior remain explicit.
  • R2 research in the record: none; source/reuse analysis remains in this description.
  • R3 evidence naming a change: none; verification identifies observable behavior and failure signals.
  • R4 rejected alternatives: comparisons remain here while no owner decision is recorded.
  • R5 standing change references: no issue or PR links remain in the record.
  • R6 ruled open questions: none; OQ1-OQ4 are genuinely unanswered.

Scope

  • Specification records only; no implementation.
  • Observable contracts preserve equivalent private implementations.
  • Native modal cooperation has an explicit ownership boundary.
  • Verification names evidence and failure signals, not workflow topology.
  • Canonical owners and overlapping work are identified.
  • No private operational context is included.

Validation

  • node scripts/check-knowledge.mjs (the pnpm check:knowledge script): passed; all knowledge templates and records are aligned.
  • Exact-file Prettier: passed.
  • git diff --check: passed.
  • Independent specification critique incorporated; no implementation readiness is claimed.
  • Exact reviewed head: 419bbed8628d2fc5b3bd6b6d83128d639c441cab.
  • Base: 37c057574712701eaeb6259cf8f0c8c0df971f70.
  • Current global-baseline routing completed at that exact base/head: 233 claim/trigger matches, with record IDs, claim IDs, reasons and content digests retained in the review receipt. Those routes do not grant blanket authority; direct shell and module owners still decide the four open questions.
  • Runtime tests and browser captures are not claimed for a specification-only change.

@vercel

vercel Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Oct 25, 2026 2:46pm UTC

Request Review

@astracat-bot

astracat-bot Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

AI review status for this pull request.

Review status Updated
❓ Needs maintainer input (for maintainers only) Oct 28, 2026, 4:19 AM UTC

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 25, 2026

@astracat-bot astracat-bot Bot 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.

This draft spec can't be approved yet. No current spec covers its new AppShell plugins API and Focus Mode (FR1–FR14), so an engineering owner needs to decide OQ1–OQ4, including whether region descriptors should be able to replace children and padding alongside the existing slot props, or carry only isHidden. An engineering owner records that decision by commenting /approve-spec <full head SHA> on this pull request; as an engineering owner, you can do so yourself. Whatever the decision, these points conflict with current records and need fixing:

  • FR7 moves focus to main when the drawer closes, but the current MobileNav contract (FR6) returns focus to an opener that is still connected. Either name that amendment in Current-state impact or make FR7 conform.
  • Under reduced motion the record settles changes immediately, but the current reduced-motion design (DR2) requires an opacity-only cross-fade of 200 ms or less on touch screens.
  • FR9's --ease-standard and the animation of the space navigation releases predate the current theme-motion spec (AST-108) and AppShell's FR17. Please reconcile them when you rebase.

[Automated review]

MobileNav's native dialog closes and releases page inertness before its
Activity boundary suspends cleanup. Its ordinary restoration to the opener
does not target navigation that is becoming hidden: the cooperating drawer
completes native close, suppresses that obsolete restoration, and hands focus

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The current MobileNav contract (FR6) returns focus to the recorded opener whenever it is still connected, and an opener inside a region Activity hides stays connected. Suppressing that restoration changes MobileNav's contract, so please name FR6 (and AR2) in Current-state impact as claims this record amends, or make this requirement conform.

this contract does not raise their floor.
- The React support floor remains the Core package's peer dependency. Activity
capability and effect-lifecycle compatibility are separate from CSS support.
- Reduced motion and an unsupported transition enhancement settle immediately

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Under a coarse primary pointer, the current reduced-motion design (DR2) requires an opacity-only cross-fade of 200 ms or less, not an immediate change. Consider stating that visibility transitions follow reduced-motion DR1–DR3 and DR2a, as AppShell's FR17 and MobileNav's FR7 do.

entry animation or a flash of the opposite state. Only subsequent visibility
changes animate. A post-hydration breakpoint correction alone does not count
as a Focus Mode action. `spec:AST-013` FR9 and FR13 remain applicable.
- **FR9 — Motion remains token-based.** Shell motion uses `--duration-medium`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

In the current theme-motion spec (AST-108 FR2), --ease-standard is the exits' curve and stays the same at every character; entrances and moves read --ease-entrance and --ease-move. AppShell's FR17 also says the content area never animates its width. Please say which motion each part of the transition uses and how it relates to FR17.

This branch was successfully deployed

1 active deployment
Preview — 419bbed8 Deployed Oct 25, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant