[Feature Request]: Backport "Add setSelectionRange to PromptInput" to `Textarea` component
Description
There was a recent commit that exposed the setSelectionRange to PromptInput, but it'd be extremely useful to expose it on the Textarea component as well.
I'd also request exposing the selectionStart and selectionEnd values as well, since without them, the set method itself isn't super useful.
Code of Conduct
- [x] I agree to follow this project's Code of Conduct
- [x] I checked the current issues for duplicate requests
Could you let us know more about your use-case for this? Previous use-cases we've seen haven't needed the selectionStart/End values, so I'm interested to better understand what exactly you're trying to achieve, to make sure this is the best approach.
Without being able to read the current values, it makes it impossible to keep a persistent cursor after modifying values. For an example, I'm using the Textarea component as a very simple/minimal code editor, so Tab needs to insert 2 spaces, not move the focus to another element. In order to achieve that, I need to update the component's value, then take the current cursor position and add 2 to it, etc.
There's limited value in only being able to blindly set a new selection range while not being able to access to current selection at all. Currently I need to wrap the Textarea component in a div so I can get a ref to the actual DOM element, which is not ideal. If Cloudscape offered some type of escape hatch to at least access the bare DOM element, you wouldn't need to support selectionStart and selectionEnd specifically, but right now, it's impossible to pass a ref or access the DOM element itself, so it makes use cases like tab to insert a space very difficult and require extra boilerplate/wrapper code.
If you're building a code editor I think you would be better starting with native components and styling them using design tokens, as this is quite a bit beyond the expected use-cases of the textarea component. Recreating the styling should be relatively straightforward as the component itself is not too complex (https://github.com/cloudscape-design/components/blob/main/src/textarea/index.tsx), and this would then give you complete control.
This issue will automatically resolve if we don't hear back from you soon.
So I understand not trying to make the textarea some super complex thing, but in my case, I'm literally just adding support for Tab and Shift + Tab to do indenting, in which case recreating the entire existing Textarea component is a bit overkill.
Is there a reason Cloudscape couldn't support at least some type of escape hatch? I understand not wanting to support a bunch of things as first-class features (e.g. exposing setSelectionRange or others directly on the component), but could Cloudscape at least support a generic property that would forward a ref to the underlying DOM element?
Right now, I have to do something like this, which is just a bit ugly/hacky and Cloudscape seems to be unnecessarily restrictive in this usecase:
const textareaRef = useRef(null);
useEffect(() => {
if (textareaRef.current.tagName !== 'DIV') return;
textareaRef.current = textareaRef.current.querySelector('textarea');
textareaRef.current.style.fontFamily = 'monospace';
}, []);
return (
<div ref={textareaRef}>
<Textarea ... />
</div>
);
tl;dr - recreating hundreds of lines of existing code/components just so I can add 3 custom lines of my own code seems a bit overkill.
We do not currently support such 'escape hatches' on any of our components, because it would be hard to give meaningful promises about the backwards compatibility of them when making future changes or additions to our components.
For example, in your code snippet above you're also overriding the style of the element, which is exactly the sort of thing that could easily break in the future if we make changes to internal styling. For this reason, we explicitly choose to provide smaller yet tested and trustable APIs.
This issue will automatically resolve if we don't hear back from you soon.
While I understand where the Cloudscape team is coming from, I'd like to at least acknowledge recreating hundreds of lines of code simply to change a font or get the current cursor position seems a bit insane. If you supported some type of escape hatch, you wouldn't need to maintain backward compatibility with anything. The point of an escape hatch is to break out, it'd be up to the people using it at that point to ensure things work or don't work.
Ultimately, I understand not wanting to support an infinite and ever growing list of features, but for some basic components like Input, Textarea, etc. supporting some way to access the base DOM element seems like an appropriate balance. For now I guess I'll just keep relying on the ref wrapper hack since it's still significantly less code than recreating entire components from scratch just to modify or access a single property.
@purplepenguin2 Have you considered using the native <textarea> element and styling it to match the Cloudscape one using Cloudscape's design tokens?