Repository: streamlit/streamlit

Issue:
Change the height of a text_area
### Problem

It would be nice to change the height of a text area. [Our users agree](https://discuss.streamlit.io/t/adjust-the-height-of-the-text-area/175). :)

### Solution

Perhaps a `height` kwarg, like we have [for `st.dataframe`](https://streamlit.io/docs/api.html?highlight=dataframe#streamlit.dataframe)?


Discussion:
Hey @treuille . I am pretty new to opensource. Can I pick this up?
Can we also set the maximum number of characters the text area can contain? Right now, it seems that there is no limit to the number of characters in text area? This can be an overkill if you want to expose your app for external users for testing. I would love to have the option to either set the max number of characters to avoid overloading or leave it open as is. I hope this makes sense.

Update: Just linking this issue since it's related.
https://github.com/streamlit/streamlit/issues/613

+1 for this *or* to allow injecting additional CSS, as suggested in #427
Are there any updates on this ?
Currently working on a project where I need to be able to edit a .json file. 
Scrolling through it with the current text_area aint no fun, because it is only 4 rows high. Thus an adjustable height for the text_area would be very sweet.
I am using the text area to custom assemble a feedback comment and the height is limiting it, i.e. it is more difficult for our clients to use it with only 4 lines of height, so this feature would be great!
I hope Streamlit team can add this feature soon. I also hope users will be able to resize the text area manually if they wish.

Resolving patch:
diff --git a/lib/streamlit/DeltaGenerator.py b/lib/streamlit/DeltaGenerator.py
--- a/lib/streamlit/DeltaGenerator.py
+++ b/lib/streamlit/DeltaGenerator.py
@@ -311,7 +311,7 @@ def _cursor(self):
     def _get_coordinates(self):
         """Returns the element's 4-component location as string like "M.(1,2).3".
 
-        This function uniquely identifies the element's position in the front-end, 
+        This function uniquely identifies the element's position in the front-end,
         which allows (among other potential uses) the MediaFileManager to maintain
         session-specific maps of MediaFile objects placed with their "coordinates".
 
@@ -2240,7 +2240,7 @@ def text_input(self, element, label, value="", key=None, type="default"):
         return str(current_value)
 
     @_with_element
-    def text_area(self, element, label, value="", key=None):
+    def text_area(self, element, label, value="", height=None, key=None):
         """Display a multi-line text input widget.
 
         Parameters
@@ -2250,6 +2250,9 @@ def text_area(self, element, label, value="", key=None):
         value : any
             The text value of this widget when it first renders. This will be
             cast to str internally.
+        height : int or None
+            Desired height of the UI element expressed in pixels. If None, a
+            default height is used.
         key : str
             An optional string to use as the unique key for the widget.
             If this is omitted, a key will be generated for the widget
@@ -2276,6 +2279,9 @@ def text_area(self, element, label, value="", key=None):
         element.text_area.label = label
         element.text_area.default = str(value)
 
+        if  height is not None:
+            element.text_area.height = height
+
         ui_value = _get_widget_ui_value("text_area", element, user_key=key)
         current_value = ui_value if ui_value is not None else value
         return str(current_value)


Test patch:
diff --git a/frontend/src/components/widgets/TextArea/TextArea.test.tsx b/frontend/src/components/widgets/TextArea/TextArea.test.tsx
--- a/frontend/src/components/widgets/TextArea/TextArea.test.tsx
+++ b/frontend/src/components/widgets/TextArea/TextArea.test.tsx
@@ -143,6 +143,20 @@ describe("TextArea widget", () => {
     )
   })
 
+  it("should set widget height if it is passed from props", () => {
+    const props = getProps({
+      height: 500,
+    })
+    const wrapper = shallow(<TextArea {...props} />)
+    const overrides = wrapper.find(UITextArea).prop("overrides")
+
+    // @ts-ignore
+    const { height, resize } = overrides.Input.style
+
+    expect(height).toBe("500px")
+    expect(resize).toBe("vertical")
+  })
+
   describe("On mac it should", () => {
     Object.defineProperty(navigator, "platform", {
       value: "MacIntel",
diff --git a/lib/tests/streamlit/text_area_test.py b/lib/tests/streamlit/text_area_test.py
--- a/lib/tests/streamlit/text_area_test.py
+++ b/lib/tests/streamlit/text_area_test.py
@@ -43,6 +43,15 @@ def test_value_types(self):
             self.assertEqual(c.label, "the label")
             self.assertTrue(re.match(proto_value, c.default))
 
+    def test_height(self):
+        """Test that it can be called with height"""
+        st.text_area("the label", "", 300)
+
+        c = self.get_delta_from_queue().new_element.text_area
+        self.assertEqual(c.label, "the label")
+        self.assertEqual(c.default, "")
+        self.assertEqual(c.height, 300)
+
 
 class SomeObj(object):
     pass