From 5288e09b2793b80f30f94fd68e781d0a5ec89937 Mon Sep 17 00:00:00 2001 From: April Hall Date: Fri, 7 Feb 2025 18:48:10 -0500 Subject: [PATCH] feat: Add auto-resize on text input --- src/lib/components/ui/textarea/index.ts | 28 ++++++++++++ .../components/ui/textarea/textarea.svelte | 43 +++++++++++++++++++ src/lib/functions/autoresize.svelte.ts | 14 ++++++ src/routes/channel/[channel]/+page.svelte | 7 +-- 4 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 src/lib/components/ui/textarea/index.ts create mode 100644 src/lib/components/ui/textarea/textarea.svelte create mode 100644 src/lib/functions/autoresize.svelte.ts diff --git a/src/lib/components/ui/textarea/index.ts b/src/lib/components/ui/textarea/index.ts new file mode 100644 index 0000000..6eb6ba3 --- /dev/null +++ b/src/lib/components/ui/textarea/index.ts @@ -0,0 +1,28 @@ +import Root from "./textarea.svelte"; + +type FormTextareaEvent = T & { + currentTarget: EventTarget & HTMLTextAreaElement; +}; + +type TextareaEvents = { + blur: FormTextareaEvent; + change: FormTextareaEvent; + click: FormTextareaEvent; + focus: FormTextareaEvent; + keydown: FormTextareaEvent; + keypress: FormTextareaEvent; + keyup: FormTextareaEvent; + mouseover: FormTextareaEvent; + mouseenter: FormTextareaEvent; + mouseleave: FormTextareaEvent; + paste: FormTextareaEvent; + input: FormTextareaEvent; +}; + +export { + Root, + // + Root as Textarea, + type TextareaEvents, + type FormTextareaEvent, +}; diff --git a/src/lib/components/ui/textarea/textarea.svelte b/src/lib/components/ui/textarea/textarea.svelte new file mode 100644 index 0000000..e0face7 --- /dev/null +++ b/src/lib/components/ui/textarea/textarea.svelte @@ -0,0 +1,43 @@ + + + diff --git a/src/lib/functions/autoresize.svelte.ts b/src/lib/functions/autoresize.svelte.ts new file mode 100644 index 0000000..96272a7 --- /dev/null +++ b/src/lib/functions/autoresize.svelte.ts @@ -0,0 +1,14 @@ +export function autoResize(node: HTMLElement) { + function resize() { + node.style.height = 'auto'; + node.style.height = node.scrollHeight + 'px'; + } + + $effect(() => { + resize(); + node.addEventListener('input', resize); + return () => { + node.removeEventListener('input', resize); + }; + }); +} diff --git a/src/routes/channel/[channel]/+page.svelte b/src/routes/channel/[channel]/+page.svelte index dba8f34..9280563 100644 --- a/src/routes/channel/[channel]/+page.svelte +++ b/src/routes/channel/[channel]/+page.svelte @@ -2,7 +2,7 @@ import { page } from '$app/state'; import Message from '$lib/components/message.svelte'; import { Button } from '$lib/components/ui/button/index'; - import { Input } from '$lib/components/ui/input/index'; + import Textarea from '$lib/components/ui/textarea/textarea.svelte'; import Websocket from '$lib/functions/clientWebsocket.svelte'; import type { TypeMessage } from '$lib/types'; import Send from 'lucide-svelte/icons/send'; @@ -10,6 +10,7 @@ import { onMount } from 'svelte'; import { v4 as uuidv4 } from 'uuid'; import type { PageData } from './$types'; + import { autoResize } from '$lib/functions/autoresize.svelte'; const { data }: { data: PageData } = $props(); @@ -50,7 +51,7 @@ socket?.sendMessage(user!, msg); msg = ''; }}> - - +