Textarea.svelte 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. <script lang="ts">
  2. import { onMount, tick } from 'svelte';
  3. export let value = '';
  4. export let placeholder = '';
  5. export let rows = 1;
  6. export let minSize = null;
  7. export let maxSize = null;
  8. export let required = false;
  9. export let className =
  10. 'w-full rounded-lg px-3.5 py-2 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-hidden h-full';
  11. let textareaElement;
  12. // Adjust height on mount and after setting the element.
  13. onMount(async () => {
  14. await tick();
  15. resize();
  16. requestAnimationFrame(() => {
  17. // setInterveal to cehck until textareaElement is set
  18. const interval = setInterval(() => {
  19. if (textareaElement) {
  20. clearInterval(interval);
  21. resize();
  22. }
  23. }, 100);
  24. });
  25. });
  26. const resize = () => {
  27. if (textareaElement) {
  28. textareaElement.style.height = '';
  29. let height = textareaElement.scrollHeight;
  30. if (maxSize && height > maxSize) {
  31. height = maxSize;
  32. }
  33. if (minSize && height < minSize) {
  34. height = minSize;
  35. }
  36. textareaElement.style.height = `${height}px`;
  37. }
  38. };
  39. </script>
  40. <textarea
  41. bind:this={textareaElement}
  42. bind:value
  43. {placeholder}
  44. class={className}
  45. style="field-sizing: content;"
  46. {rows}
  47. {required}
  48. on:input={(e) => {
  49. resize();
  50. }}
  51. on:focus={() => {
  52. resize();
  53. }}
  54. />