Skip to content

docs(useOverlay): add hook docs and a product quick view example block - #9908

Merged
cixzhang merged 4 commits into
meta:mainfrom
MannXo:docs/9559-useoverlay-example
Nov 5, 2026
Merged

cixzhang merged 4 commits into
meta:mainfrom
MannXo:docs/9559-useoverlay-example

Conversation

@MannXo

@MannXo MannXo commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Reader impact

useOverlay has no HookDoc, so it has no docsite page and astryx hook useOverlay finds nothing. After this change it has a page with its options, its four return values and how keyboard reveal works, and an example. A product Card spreads the hook's containerRef and containerProps and renders the returned scrim once over its image, as a strip along the bottom. Hovering the card, or moving keyboard focus into it, slides in a Quick view button, and leaving hides it again. The image is a link that stays clickable above the strip, and Tab lands on it first so the next Tab reaches Quick view. astryx template useOverlayHookUsage <path> copies it.

Source of truth

  • packages/core/src/Overlay/useOverlay.tsx (options, containerProps, element and renderOverlay, the touch toggle) and OverlayScrim.tsx for the CSS-driven reveal from the container's :hover and :focus-within.
  • The Overlay prop descriptions in Overlay.doc.mjs, which the option descriptions follow.
  • architecture:knowledge-contracts INV28.

Correction

  • Adds packages/core/src/Overlay/useOverlay.doc.mjs (docs + docsDense, group: 'Overlay', importPath: '@astryxdesign/core/Overlay'), in the shape useLightbox.doc.mjs uses. Its usage text says that hidden content is not focusable, so the container needs a focusable element before it in tab order. That is what makes showOn: 'hover' reachable from the keyboard. It also says that a revealed scrim takes pointer input over the area it covers, so that element belongs outside the scrim, or above or below a strip.
  • Adds blocks/components/Overlay/useOverlayHookUsage (exampleFor: 'useOverlay'). It calls useOverlay({showOn: 'hover', position: 'bottom', align: 'center', content: <Button label="Quick view" ... />}), spreads containerRef and containerProps on the Card, and renders overlay.element inside a position: relative image section, after the image link, as the Overlay storybook's DisconnectedHover story does. containerRef is cast to RefObject<HTMLDivElement | null> for Card's ref, as in that story.
  • Updates the recorded module resolution for useOverlay in packages/cli/api/component/__fixtures__/resolutions/modules.txt (it now opens Overlay/useOverlay.doc.mjs instead of falling back to Overlay/Overlay.doc.mjs), as test: main is green again: Tokenizer's sheet-row test passes presentation, and the recorded module resolutions follow core #9851 did for useLightbox.

Evidence

  • Real Chromium (Playwright against the docsite dev server, /components/useOverlay, 1280x900). Scrim computed visibility / opacity:

    State Scrim Focus
    At rest hidden / 0
    Pointer over the image visible / 1
    Pointer leaves hidden / 0
    Image link focused visible / 1 #ceramic-mug link
    Tab visible / 1 Quick view
    Tab again (focus leaves the card) hidden / 0

    No page errors. That run used the default fill scrim.

  • A second Chromium run after the move to position: 'bottom'. With the pointer over the card, Quick view is visible in a strip at y 534 to 562 of an image spanning y 296 to 574, elementFromPoint 30% down the image is the link, and a click there sets location.hash to #ceramic-mug. With the fill default, the revealed scrim covers that point and takes the click (pointerEvents: 'auto' in OverlayScrim.tsx).

  • Test (packages/cli/api/template/use-overlay-hook-usage.test.tsx, 3 cases). jsdom applies no CSS, so it checks the wiring. The Card carries every class of containerProps.className, one Quick view renders inside it in a scrim with data-position="bottom" (fails with the fill default), and the image link comes before Quick view in document order.

Scope

  • This PR changes documentation only, or names every necessary generated artifact. The generated artifacts are the block's route and the hook's route in internal/shadcn-registry/routes.lock.json, the block's sandbox route in apps/sandbox/scripts/next-export-routes.json, and the recorded resolution above.
  • Runtime, API, visual, and policy changes were removed or split.
  • Public text and artifacts contain no internal Meta context.

Testing

  • vitest run --project node packages/cli/foundation/discovery packages/cli/api/template packages/cli/assets/templates internal/shadcn-registry apps/sandbox/src/route-manifest.test.ts packages/cli/api/build/tree.test.mjs packages/cli/test/experimental-isolation.test.mjs packages/cli/api/component packages/cli/api/docs packages/cli/api/hook: 1576 passed, 0 failed.
  • vitest run --project ui packages/core/src/docPropLiterals.test.ts packages/core/src/docPropReferences.test.ts: 22 passed.
  • apps/docsite: pnpm generate, then vitest run src/__tests__/data-extraction.test.ts src/__tests__/example-coverage.test.ts: 136 passed, 0 failed. The route lock check is clean after UPDATE_SHADCN_ROUTE_LOCK=1 added the two routes.
  • pnpm lint:strict: clean (0 errors).
  • pnpm -F @astryxdesign/cli typecheck: clean.
  • node scripts/release/changeset-coverage.mjs pr --base upstream/main --head HEAD --released v0.7.8: passes. Changeset names @astryxdesign/core and @astryxdesign/cli, patch, [docs].
  • .github/scripts/check-public-text.mjs over this commit, title and description: no findings.
  • Not run: the full pnpm test suite, and a touch device (the tap toggle).

Notes for reviewers

UseOverlayOptions.showOn's source comment says a strip stays visible on touch and only a fill overlay toggles on tap, but useOverlay sets needsTouchToggle for every hover overlay on a (hover: none) device, whatever its position. The new doc describes what the code does (a hover overlay toggles on tap). If the comment is the intended behavior, that is a separate fix in the hook.

Fixes #9559

@vercel

vercel Bot commented Nov 4, 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 Nov 5, 2026 6:52pm UTC

Request Review

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

astracat-bot Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Nov 5, 2026, 6:42 PM UTC

@github-actions github-actions Bot added community Authored by a community contributor (not on the eng/design team) needs:code-review High-risk change (new package/component/API) — needs human code review before merge needs:design-review Affects visuals — Design should review labels Nov 4, 2026
@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · 2ab6a3e

This branch's preview address cannot be known in advance; open it from Vercel's comment.

Modified components

Component Size LoC Visual · A11y · RTL
Overlay 21.6 kB (0) · 3.9 kB CSS (0) 458 (0) ✓ · ✓ · ✓

Package size:

  • @astryxdesign/cli 3.37 MB packed (+618 B); no new dependencies
  • @astryxdesign/core 6.61 MB packed (+1.8 kB); no new dependencies

API changes: none in this pull request

Committed API report behind this build: cli 19 rows, core 23 rows; run pnpm api:report.

Touched components checked; add ci:run-visual, ci:run-a11y or ci:run-rtl to run the full suites.


Generated by PR Enrichment workflow | View full report

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for closing the useOverlay docs gap: the hook doc matches what the hook does, and the example wires containerRef, containerProps and element the way readers need. One change is needed before this can merge:

  • The example's image link sits under the hook's fill scrim, which takes pointer input once the card is hovered, so a mouse click on the image never follows the link while keyboard Enter does (useOverlayHookUsage.tsx lines 26-36); keep the link uncovered, for example with position: 'bottom' or by moving the link to the product name ahead of the image, and update the hook doc's "a link around the image" advice to match.

CI has not run on this head yet; a maintainer adds the ci:run label so it runs.

[Automated review]

ref={overlay.containerRef as RefObject<HTMLDivElement | null>}
{...overlay.containerProps}>
<div style={{position: 'relative'}}>
<a href="#ceramic-mug">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Once the card is hovered, the fill scrim rendered by overlay.element below covers this whole link with pointer-events: auto, so a mouse click on the image lands on the scrim and the link is not followed (keyboard Enter does follow it). position: 'bottom' keeps the image above the strip clickable with the same tab order; moving the link to the product name ahead of the image also works.

],
usage: {
description:
"Adds overlay behavior to a container you already render, such as a Card or a custom media frame, without the wrapper Overlay adds. Spread containerRef and containerProps on the container, then render element (or renderOverlay(children)) once inside it. The scrim is absolutely positioned, so it covers the nearest positioned ancestor: the container itself, or a positioned section inside it such as an image area. Visibility is CSS-driven from the container's :hover and :focus-within, so with showOn 'hover' a keyboard user reveals the content by moving focus into the container. Hidden content is not focusable, so the container needs a focusable element before the overlay content in tab order, such as a link around the image.",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

"such as a link around the image": with the default fill scrim, that link is covered and cannot be clicked with a mouse while the overlay shows. Worth saying that a revealed scrim takes pointer input over the area it covers, and suggesting a focusable element outside it (or a top or bottom strip).

… stays clickable

A revealed fill scrim takes pointer input over the whole image, so a mouse
click on the image never reached its link. The hook doc now says so.

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the update: with the bottom strip, the example's image link stays clickable above Quick view, and the hook doc now explains that a revealed scrim takes pointer input over the area it covers. The hook doc matches what useOverlay does, and the block shows the hover, focus and Tab path the issue asks for.

Approved pending CI: CI has not run on this head yet; a maintainer adds the ci:run label so it runs.

[Automated review]

@cixzhang cixzhang added the ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) label Nov 5, 2026
@cixzhang cixzhang closed this Nov 5, 2026
@cixzhang cixzhang reopened this Nov 5, 2026
Resolves the generated route lists (the union of both sides' entries, in generator format) and refreshes any generated goldens; no other change.

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for keeping this current with main. The useOverlay hook doc matches what the hook does, and the product card example shows the hover, keyboard-focus and Tab path that #9559 asks for, with the image link still clickable above the Quick view strip. CI passed on this head, and no changes are needed.

[Automated review]

@github-actions github-actions Bot removed the needs:code-review High-risk change (new package/component/API) — needs human code review before merge label Nov 5, 2026
@cixzhang
cixzhang merged commit c8a172b into meta:main Nov 5, 2026
69 checks passed

This branch was successfully deployed

1 active deployment
Preview — 2ab6a3eb Deployed Nov 5, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) CLA Signed This label is managed by the Meta Open Source bot. community Authored by a community contributor (not on the eng/design team) needs:design-review Affects visuals — Design should review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs(useOverlay): add hook docs and a minimal live example

2 participants