-
-
Notifications
You must be signed in to change notification settings - Fork 245
feat(textarea): 718 - Add Textarea component #2898
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
base: master
Are you sure you want to change the base?
Conversation
Add a native, unstyled textarea component that integrates with the Field system to provide automatic state handling and validation. Enable content-aware auto-resizing via minRows/maxRows, support controlled and uncontrolled usage, and expose data attributes for styling based on control state. Add documentation, API reference, unit tests, and package export so the component is discoverable and consumable.
commit: |
✅ Deploy Preview for base-ui ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Bundle size report
|
const lineHeight = parseFloat(getComputedStyle(el).lineHeight) || 24; | ||
const min = minRows != null ? minRows * lineHeight : 0; | ||
const maxPx = maxRows != null ? maxRows * lineHeight : Infinity; | ||
const target = Math.min(maxPx, Math.max(min, el.scrollHeight)); |
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.
Is this enough to do the calculation like this? 🤔
Other libraries like Material UI and react-textarea-autosize
render a second, hidden textarea
element presumably to handle edge cases
Check out:
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.
Thanks for reviewing!
The direct scrollHeight
+ lineHeight
math works for the simple case, but at a glance you’re definitely right: Material UI and react-textarea-autosize
handle things like box-sizing quirks, padding, and browser edge cases with the hidden textarea
element. I’ll review their approach and see how we can adopt a similar pattern instead.
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.
Perhaps some research into when field-sizing
might be at 90%+ support would be helpful too. When it's widely supported, we won't need this functionality in JS. https://caniuse.com/?search=field-sizing
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.
Absolutely, would be great to drop the JS once browser support crosses the 90% mark. Do you have a usual way to track when features hit that kind of support? Just Can I Use, or anything more automated you follow?
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.
nothing automated
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.
Alright, I’ve updated things to better align with MUI’s approach and logic.
I also added a dedicated demo for field-sizing that explains the current browser support.
Removes usage of the experimental field-sizing property and related Tailwind utility from textarea examples and removes hardcoded min-height in CSS modules. Avoids depending on a feature with limited browser support (~71.47%). Adds space to create a dedicated example and documentation with compatibility research once support reaches ~90%, keeping demos stable and predictable in the meantime.
…nto feat/718-Textarea
…textarea for improved performance
Extracts the textarea height calculation into a reusable utility and isolates the expensive measurement logic. Reduces layout thrashing by tracking last-applied height and overflow to avoid redundant DOM writes, and introduces debounced scheduling (~166ms) for resize/observer events while using immediate RAF for input events to keep input responsive. Adds proper timer/observer cleanup and a default rows fallback to ensure consistent initial sizing and improved runtime performance.
Replace a hardcoded property list and unsafe direct assignments with iteration over computed styles and setProperty/getPropertyValue to copy relevant CSS keys. This avoids TypeScript readonly casts, picks up actual computed property names (including vendor-prefixed variants), and makes style copying more robust and cross-browser resilient.
…e textarea height calculations.
Remove built-in inline "resize: none" from textarea rendering. Allow consumers to control resizing via their own CSS instead of enforcing non-resizable behavior. Preserve existing value/rows handling; change affects styling only.
Adds interactive demos showing CSS field-sizing for the textarea component using CSS Modules and Tailwind, and updates documentation to explain the feature, browser support, and recommended fallback guidance. Provides examples to let developers try native field-sizing behavior, clarifies current limited browser support, and notes a plan to adopt field-sizing by default once support reaches sufficient coverage.
@Jacksonmills this is a great first iteration. The team is a bit busy this week with React Conf, but we can come back to this in the next weeks. Thanks for putting in the effort :) |
ofc no worries! |
|
||
Because support is incomplete, the demo may not work in older browsers or Safari `<26`. If the textarea doesn't resize, try a **current Chrome or Edge** build. | ||
|
||
> Once support passes ~90 %, we plan to switch the Textarea component to `field-sizing` by default, dropping the JS fallback. |
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.
I do find this quite optimistic. Would it be possible to just check for support and gate the resizing logic instead with CSS.supports("field-sizing", "content")
?
Add the new
Textarea
(#718) component to provide an unstyled native text input with Field system integration:<Textarea … />
with support for controlled and uncontrolled usage.minRows
andmaxRows
.docs/src/app/(public)/content/react/components/textarea
.This is my first time adding a form control to base-ui. I’m following the repo’s patterns and totally down to adjust if this component needs tweaks.
Changed files
packages/react/src/textarea/Textarea.tsx
packages/react/src/textarea/index.ts
docs/src/app/(public)/content/react/components/textarea/*
packages/react/src/textarea/Textarea.test.tsx