Repository navigation
docs(useOverlay): add hook docs and a product quick view example block - #9908
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
PR Analysis Report🔎 Preview ·
|
| 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
There was a problem hiding this comment.
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.tsxlines 26-36); keep the link uncovered, for example withposition: '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"> |
There was a problem hiding this comment.
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.", |
There was a problem hiding this comment.
"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.
There was a problem hiding this comment.
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]
Resolves the generated route lists (the union of both sides' entries, in generator format) and refreshes any generated goldens; no other change.
There was a problem hiding this comment.
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]
Reader impact
useOverlayhas no HookDoc, so it has no docsite page andastryx hook useOverlayfinds 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'scontainerRefandcontainerPropsand 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,elementandrenderOverlay, the touch toggle) andOverlayScrim.tsxfor the CSS-driven reveal from the container's:hoverand:focus-within.Overlay.doc.mjs, which the option descriptions follow.architecture:knowledge-contractsINV28.Correction
packages/core/src/Overlay/useOverlay.doc.mjs(docs+docsDense,group: 'Overlay',importPath: '@astryxdesign/core/Overlay'), in the shapeuseLightbox.doc.mjsuses. 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 makesshowOn: '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.blocks/components/Overlay/useOverlayHookUsage(exampleFor: 'useOverlay'). It callsuseOverlay({showOn: 'hover', position: 'bottom', align: 'center', content: <Button label="Quick view" ... />}), spreadscontainerRefandcontainerPropson the Card, and rendersoverlay.elementinside aposition: relativeimage section, after the image link, as the Overlay storybook's DisconnectedHover story does.containerRefis cast toRefObject<HTMLDivElement | null>for Card'sref, as in that story.useOverlayinpackages/cli/api/component/__fixtures__/resolutions/modules.txt(it now opensOverlay/useOverlay.doc.mjsinstead of falling back toOverlay/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 foruseLightbox.Evidence
Real Chromium (Playwright against the docsite dev server,
/components/useOverlay, 1280x900). Scrim computedvisibility/opacity:hidden/0visible/1hidden/0visible/1#ceramic-muglinkvisible/1hidden/0No 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,elementFromPoint30% down the image is the link, and a click there setslocation.hashto#ceramic-mug. With the fill default, the revealed scrim covers that point and takes the click (pointerEvents: 'auto'inOverlayScrim.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 ofcontainerProps.className, one Quick view renders inside it in a scrim withdata-position="bottom"(fails with the fill default), and the image link comes before Quick view in document order.Scope
internal/shadcn-registry/routes.lock.json, the block's sandbox route inapps/sandbox/scripts/next-export-routes.json, and the recorded resolution above.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, thenvitest run src/__tests__/data-extraction.test.ts src/__tests__/example-coverage.test.ts: 136 passed, 0 failed. The route lock check is clean afterUPDATE_SHADCN_ROUTE_LOCK=1added 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/coreand@astryxdesign/cli, patch,[docs]..github/scripts/check-public-text.mjsover this commit, title and description: no findings.pnpm testsuite, 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, butuseOverlaysetsneedsTouchTogglefor every hover overlay on a(hover: none)device, whatever itsposition. 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