Skip to content

Instantly share code, notes, and snippets.

@toolittlecakes
Last active December 16, 2024 14:23
Show Gist options
  • Save toolittlecakes/2cc9326e66bc601284022f63e3ecd004 to your computer and use it in GitHub Desktop.
Save toolittlecakes/2cc9326e66bc601284022f63e3ecd004 to your computer and use it in GitHub Desktop.
from streamlit.elements.lib.utils import Key, LabelVisibility
from streamlit.runtime.state.common import WidgetArgs, WidgetCallback, WidgetKwargs
def text_area_auto_height(
label: str,
value: str = "",
height: int | None = None,
max_chars: int | None = None,
key: Key | None = None,
help: str | None = None,
on_change: WidgetCallback | None = None,
args: WidgetArgs | None = None,
kwargs: WidgetKwargs | None = None,
*,
placeholder: str | None = None,
disabled: bool = False,
label_visibility: LabelVisibility = "visible",
):
html_text = f"""
<style>
div[data-testid="stVerticalBlockBorderWrapper"]:has(> div > div[data-testid="stVerticalBlock"] > div[data-testid="stElementContainer"] > div[data-testid="stHtml"] > span.{key}) {{
display: none;
}}
</style>
<span class='{key}'></span>
"""
js = f"""
<script>
const init = () => {{
const container = parent.document.querySelector('div[data-testid="stVerticalBlockBorderWrapper"]:has(> div > div[data-testid="stVerticalBlock"] > div[data-testid="stElementContainer"] > div[data-testid="stHtml"] > span.{key})');
if (!container) return;
const textarea = container.parentElement.querySelector('textarea');
textarea.style.height = 0;
textarea.style.minHeight = 'auto';
const adjustHeight = () => {{
let scrollHeight = textarea.scrollHeight;
textarea.style.height = scrollHeight - 10 + 'px';
if (textarea.scrollHeight === scrollHeight) {{
textarea.style.height = scrollHeight + 1 + 'px';
return;
}}
while (textarea.scrollHeight < scrollHeight) {{
scrollHeight = textarea.scrollHeight;
textarea.style.height = scrollHeight - 10 + 'px';
}}
textarea.style.height = textarea.scrollHeight + 1 + 'px';
}}
const resizeObserver = new ResizeObserver((entries) => {{
for (const entry of entries) {{
const textarea = entry.target
adjustHeight(textarea)
}}
}})
textarea.addEventListener('input', e => {{
adjustHeight(e.target)
}})
//resizeObserver.observe(textarea)
adjustHeight();
}}
document.addEventListener('DOMContentLoaded', init);
</script>
"""
with st.container():
with st.container():
st.html(html_text)
html(js, height=0)
text_area = st.text_area(
label,
value,
key=key,
help=help,
on_change=on_change,
args=args,
kwargs=kwargs,
placeholder=placeholder,
disabled=disabled,
label_visibility=label_visibility,
)
return text_area
if __name__ == "__main__":
text_area_auto_height("test", "test")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment