Skip to content

docs(hooks): add useMergedRefs AutoGrowTextArea example block - #9938

Merged
cixzhang merged 4 commits into
meta:mainfrom
Sainath-Reddy7:gh-9492-useMergedRefs-example
Nov 5, 2026
Merged

cixzhang merged 4 commits into
meta:mainfrom
Sainath-Reddy7:gh-9492-useMergedRefs-example

Conversation

@Sainath-Reddy7

Copy link
Copy Markdown
Contributor

Reader impact

Readers of the useMergedRefs docsite page had no live example: the hook is documented for the exact "forwarded ref plus internal measurement" use case, but INV28 requires every public hook to have a runnable example block, and useMergedRefs had none. After this change the Examples section renders an AutoGrowTextArea that forwards the caller's ref and keeps its own ref to measure itself, with a parent button focusing the box through the forwarded ref while the component still resizes on input.

Source of truth

  • Hook: packages/core/src/hooks/useMergedRefs.ts
  • Hook doc (usage.bestPractices names this exact scenario): packages/core/src/hooks/useMergedRefs.doc.mjs
  • Contract: INV28 in docs/architecture/knowledge-contracts.md
  • Issue: docs(useMergedRefs): add a minimal live example #9492

Correction

Adds the missing example rather than correcting text: a Hooks/useMergedRefsHookUsage template block pair (.tsx + .doc.mjs with exampleFor: 'useMergedRefs'), following the shape of Hooks/useHotkeysHookUsage and Theme/useThemeHookUsage. The block imports only public entry points (@astryxdesign/core/hooks, …/Card, …/Button, …/Layout, …/Text); visible behavior comes from the hook itself — without useMergedRefs the single textarea ref slot cannot serve both the forwarded focus ref and the self-measurement ref.

Also adds /templates/useMergedRefsHookUsage/ to the checked sandbox export oracle, per apps/sandbox/README.md ("review and update the checked scripts/next-export-routes.json route list along with the change").

Evidence

  • node scripts/sync-templates.js runs clean and generates the deterministic route wrapper for the new block (byte-identical output for all existing wrappers); wrappers are gitignored and regenerate in CI via pnpm generate.
  • Prettier (repo config) passes on both new files.
  • Acceptance criteria from docs(useMergedRefs): add a minimal live example #9492 checked: exampleFor names the hook; removing the hook breaks what the example shows; no unrelated UI or styling.

Scope

  • This PR changes documentation only, or names every necessary generated artifact.
  • Runtime, API, visual, and policy changes were removed or split.
  • Public text and artifacts contain no internal Meta context.

Testing

Generated-artifact verification (sync-templates.js determinism) and formatting locally; docs build and the export-oracle contract test run in CI. pnpm review:pre was not run locally (no full toolchain on this machine) — noted for reviewers; CI covers the docs build.

Fixes #9492


AI assistance disclosure: the example block and oracle update were prepared with an AI coding agent (GLM-5.3) under my direction; I reviewed each line, ran the sync determinism check and formatting, and stand behind the change.

Fulfills INV28 for useMergedRefs: a live template block whose
AutoGrowTextArea forwards the caller's ref and keeps its own ref to
measure scrollHeight, with useMergedRefs attaching both to the same
textarea. A parent button focuses the box through the forwarded ref
while the component still resizes itself. Adds the block's sandbox
export route to the checked oracle.

Fixes meta#9492
@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 4:39pm UTC

Request Review

@meta-cla

meta-cla Bot commented Nov 4, 2026

Copy link
Copy Markdown

Hi @Sainath-Reddy7!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@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, 4:46 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

@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 picking up #9492: the example shows the hook doing the job its docs describe, and both the focus button and the auto-grow work. A few changes are needed before it can merge:

  • Run UPDATE_SHADCN_ROUTE_LOCK=1 node apps/docsite/scripts/generate-data.mjs and commit the one entry it adds to internal/shadcn-registry/routes.lock.json (example-use-merged-refs-auto-grow-text-area), because without it the docs build stops during data generation (the Vercel preview, which runs that build, also failed on this branch).
  • Remove the caption next to the button, or move it to its own line, because in the 360 px card it cuts the button label to "Focus via forwa…".
  • Add a one-line comment above the useEffect that says it syncs the textarea's height with the committed value and why that has to happen after render, as the repository's Effect rule (INV3) and the other hook examples do.

Optional: give the textarea an aria-label, because its only accessible name is a placeholder that never shows. CI has not run on this branch yet; it runs once a maintainer adds the ci:run label.

[Automated review]

/** @type {import('@astryxdesign/cli/authoring').TemplateDoc} */
export const doc = {
type: 'block',
exampleFor: 'useMergedRefs',

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.

This block adds the shadcn item example-use-merged-refs-auto-grow-text-area (examples/use-merged-refs/auto-grow-text-area). It is not in internal/shadcn-registry/routes.lock.json, so apps/docsite/scripts/generate-data.mjs stops with "Generated ShadCN names or routes changed" and the docs build fails. Run UPDATE_SHADCN_ROUTE_LOCK=1 node apps/docsite/scripts/generate-data.mjs and commit the one entry it adds.

Comment on lines +74 to +76
<Text type="body" color="secondary">
forwarded ref + kept ref, one textarea
</Text>

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.

In the 360 px card, this caption leaves the button 115 px for its 157 px label, so the button reads "Focus via forwa…". Remove the caption, which the block description already covers, or put it on its own line.

const keptRef = useRef<HTMLTextAreaElement>(null);
const mergedRef = useMergedRefs(forwardedRef, keptRef);

useEffect(() => {

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.

Please add a note that names what this Effect syncs and why it runs after commit (react-component-runtime INV3), as the other hook examples do. For example:

// Syncs the textarea's inline height with the committed value.
// scrollHeight is right only after React writes the new text.

value={value}
onChange={event => onChange(event.target.value)}
rows={1}
placeholder="Type — the box grows itself"

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.

Optional: the textarea has no label, so its accessible name is this placeholder, which never shows because the box starts filled. An aria-label that names the field fixes that for readers who copy the pattern.

- Add the example-use-merged-refs-auto-grow-text-area entry to
  internal/shadcn-registry/routes.lock.json (the one entry
  UPDATE_SHADCN_ROUTE_LOCK=1 generate-data adds; inserted in the lock's
  sort order with the exact name/path from the generated registry).
- Drop the caption next to the focus button so the label no longer
  truncates in the 360px card; the block description covers it.
- Note above the Effect what it syncs and why it runs after commit,
  matching INV3 and the other hook examples.
- Give the textarea an aria-label so its accessible name does not
  depend on a placeholder that never shows.
@Sainath-Reddy7

Copy link
Copy Markdown
Contributor Author

Addressed all three required items and the optional one:

  • routes.lock.json: added the example-use-merged-refs-auto-grow-text-area entry. The full generate-data run needs the built monorepo toolchain, so the entry was inserted directly in the lock's sort order with the exact generated name/path from the review — CI's data-generation step is the authoritative check that it matches.
  • Caption: removed; the button now has the full row and the block description carries the explanation.
  • Effect note: added the two-line comment above the useEffect per INV3.
  • aria-label: added aria-label="Auto-growing message" to the textarea.

sync-templates.js re-run remains deterministic; prettier clean.

@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 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 quick follow-up: the caption, the Effect note and the aria-label are all in, and the example now renders and works as intended. One change is still needed before it can merge:

  • Regenerate internal/shadcn-registry/routes.lock.json with UPDATE_SHADCN_ROUTE_LOCK=1 node apps/docsite/scripts/generate-data.mjs and commit what it writes, because the five aliases arrays reformatted onto one line (from line 352) no longer match the generator's output byte for byte, so docs data generation stops with "Generated ShadCN names or routes changed" (the Vercel preview for this commit also failed).

Your new lock entry itself is exactly what the generator writes, so only the formatting changes need to go; the repository's Prettier check does not cover this JSON file. CI has not run on this branch yet; it runs once a maintainer adds the ci:run label.

[Automated review]

"aliases": [
"components/lab/drawer"
]
"aliases": ["components/lab/drawer"]

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.

This array, and the ones at lines 357, 467, 1822 and 1832, are no longer in the format the generator writes (JSON.stringify(lock, null, 2)). checkShadcnRouteLock in apps/docsite/scripts/generate-data.mjs compares the file byte for byte, so docs data generation fails with "Generated ShadCN names or routes changed". Run UPDATE_SHADCN_ROUTE_LOCK=1 node apps/docsite/scripts/generate-data.mjs and commit the lock it writes; your new example-use-merged-refs-auto-grow-text-area entry is exactly what it produces.

The previous commit's formatting pass collapsed five pre-existing
aliases arrays onto one line; the generator compares the lock byte for
byte, so restore their JSON.stringify(lock, null, 2) layout. The diff
vs main is now exactly the one new useMergedRefs entry.
@Sainath-Reddy7

Copy link
Copy Markdown
Contributor Author

Restored the generator's JSON.stringify(lock, null, 2) layout for the five aliases arrays my formatting pass had collapsed — that file deliberately stays outside Prettier. The lock diff vs main is now exactly the one new example-use-merged-refs-auto-grow-text-area entry.

@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 restoring the route lock's formatting: the lock now matches what the generator writes, the docs build passes, and the example does what #9492 asks, with the button focusing the box through the forwarded ref while the box grows as you type.

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
@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · d1331ac

Storybook · Sandbox · built from this PR's head

Package size: @astryxdesign/cli 3.34 MB packed (+871 B); no new dependencies.

API changes: none in this pull request

Committed API report behind this build: cli 8 rows, theme-butter 1 row, theme-chocolate 1 row, theme-gothic 1 row, theme-matcha 1 row, theme-neutral 1 row, theme-stone 1 row, theme-y2k 1 row; run pnpm api:report.

Not run on this PR: add ci:run-visual, ci:run-a11y or ci:run-rtl to run them.


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.

With the @astryxdesign/cli Changeset now in the pull request, the Changeset coverage check that failed on the previous revision passes, and the example still does what #9492 asks: the button focuses the box through the forwarded ref while the box grows and shrinks with its text.

Approved pending CI: CI has not run on this head yet. GitHub lists its Lint, CI and CLI Smoke Test runs as action required, so a maintainer needs to approve them before they run.

[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 b2659fe into meta:main Nov 5, 2026
59 checks passed

This branch was successfully deployed

1 active deployment
Preview — d1331ac1 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(useMergedRefs): add a minimal live example

2 participants