Repository navigation
docs(hooks): add useMergedRefs AutoGrowTextArea example block #9938
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
283c1b2
cab99a9
13b8373
d1331ac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| '@astryxdesign/cli': patch | ||
| --- | ||
|
|
||
| [docs] A `useMergedRefs — AutoGrowTextArea` example block: an AutoGrowTextArea forwards the caller's ref and keeps its own ref to measure its height, and the merged ref attaches both to the same textarea, so it resizes itself while a parent button focuses it through the forwarded ref. Copy it with `astryx template useMergedRefsHookUsage <path>`. | ||
|
|
||
| @Sainath-Reddy7 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // Copyright (c) Meta Platforms, Inc. and affiliates. | ||
|
|
||
| /** @type {import('@astryxdesign/cli/authoring').TemplateDoc} */ | ||
| export const doc = { | ||
| type: 'block', | ||
| exampleFor: 'useMergedRefs', | ||
| name: 'useMergedRefs — AutoGrowTextArea', | ||
| displayName: 'useMergedRefs — AutoGrowTextArea', | ||
| description: | ||
| "An AutoGrowTextArea that forwards the caller's ref and also keeps its own ref to measure scrollHeight. The merged ref attaches both to the same textarea: it resizes itself while a parent button focuses it through the forwarded ref.", | ||
| isReady: true, | ||
| aspectRatio: 4 / 3, | ||
| componentsUsed: ['Card', 'Button', 'Layout'], | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| // Copyright (c) Meta Platforms, Inc. and affiliates. | ||
|
|
||
| 'use client'; | ||
|
|
||
| import {forwardRef, useEffect, useRef, useState} from 'react'; | ||
| import {Button} from '@astryxdesign/core/Button'; | ||
| import {Card} from '@astryxdesign/core/Card'; | ||
| import {useMergedRefs} from '@astryxdesign/core/hooks'; | ||
| import {VStack} from '@astryxdesign/core/Layout'; | ||
|
|
||
| type AutoGrowTextAreaProps = { | ||
| value: string; | ||
| onChange: (value: string) => void; | ||
| }; | ||
|
|
||
| // Forwards the caller's ref and also keeps its own ref to measure | ||
| // scrollHeight; useMergedRefs attaches both to the same textarea. | ||
| const AutoGrowTextArea = forwardRef<HTMLTextAreaElement, AutoGrowTextAreaProps>( | ||
| function AutoGrowTextArea({value, onChange}, forwardedRef) { | ||
| const keptRef = useRef<HTMLTextAreaElement>(null); | ||
| const mergedRef = useMergedRefs(forwardedRef, keptRef); | ||
|
|
||
| // Syncs the textarea's inline height with the committed value. | ||
| // scrollHeight is right only after React writes the new text. | ||
| useEffect(() => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
| const el = keptRef.current; | ||
| if (!el) { | ||
| return; | ||
| } | ||
| el.style.height = 'auto'; | ||
| el.style.height = `${el.scrollHeight}px`; | ||
| }, [value]); | ||
|
|
||
| return ( | ||
| <textarea | ||
| ref={mergedRef} | ||
| value={value} | ||
| onChange={event => onChange(event.target.value)} | ||
| rows={1} | ||
| aria-label="Auto-growing message" | ||
| placeholder="Type — the box grows itself" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
| style={{ | ||
| width: '100%', | ||
| padding: 8, | ||
| borderRadius: 8, | ||
| border: '1px solid', | ||
| resize: 'none', | ||
| overflow: 'hidden', | ||
| fontFamily: 'inherit', | ||
| fontSize: 14, | ||
| lineHeight: '20px', | ||
| color: 'inherit', | ||
| background: 'transparent', | ||
| }} | ||
| /> | ||
| ); | ||
| }, | ||
| ); | ||
|
|
||
| export default function UseMergedRefsHookUsage() { | ||
| const areaRef = useRef<HTMLTextAreaElement>(null); | ||
| const [value, setValue] = useState( | ||
| 'This box keeps its own ref to measure and grow. The button focuses it through the forwarded ref.', | ||
| ); | ||
|
|
||
| return ( | ||
| <Card width={360} padding={4}> | ||
| <VStack gap={3}> | ||
| <AutoGrowTextArea ref={areaRef} value={value} onChange={setValue} /> | ||
| <Button | ||
| label="Focus via forwarded ref" | ||
| size="sm" | ||
| onClick={() => areaRef.current?.focus()} | ||
| /> | ||
| </VStack> | ||
| </Card> | ||
| ); | ||
| } | ||
There was a problem hiding this comment.
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 ininternal/shadcn-registry/routes.lock.json, soapps/docsite/scripts/generate-data.mjsstops with "Generated ShadCN names or routes changed" and the docs build fails. RunUPDATE_SHADCN_ROUTE_LOCK=1 node apps/docsite/scripts/generate-data.mjsand commit the one entry it adds.